@qiaolei81/copilot-session-viewer 0.3.7 → 0.3.8
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/server.min.js +35 -35
- package/package.json +1 -1
- package/public/js/homepage.min.js +4 -4
- package/public/js/session-detail.min.js +193 -74
- package/public/js/time-analyze.min.js +1 -1
- package/views/index.ejs +10 -0
- package/views/session-vue.ejs +434 -242
package/dist/server.min.js
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
var w=(
|
|
2
|
-
`)){let s=t.trim();if(!s||s.startsWith("#"))continue;let r=s.indexOf(":");if(r<=0)continue;let o=s.slice(0,r).trim(),a=s.slice(r+1).trim();o&&(n[o]=a)}return n}catch(e){return console.error(`Error parsing YAML ${u}:`,e.message),{}}}async function Ws(u,e=500){try{let n=Z.createReadStream(u,{encoding:"utf-8"}),t=X.createInterface({input:n,crlfDelay:1/0}),s="",r=null,o=null,a=null,i=null,l=!1;for await(let d of t)if(d.trim())try{let p=JSON.parse(d);if(p.timestamp){let m=new Date(p.timestamp).getTime();isNaN(m)||(r||(r=m),o=m)}if(!s&&p.type==="user.message"){let m=p.data?.message||p.data?.content||p.data?.text||"";m&&(s=m.length>e?m.substring(0,e)+"...":m)}p.type==="session.end"&&(l=!0),p.type==="session.start"&&p.data?.copilotVersion&&!a&&(a=p.data.copilotVersion),(p.type==="session.start"||p.type==="session.model_change")&&!i&&(p.data?.selectedModel?i=p.data.selectedModel:p.data?.newModel?i=p.data.newModel:p.data?.model&&(i=p.data.model))}catch{}t.close(),n.destroy();let c=r&&o&&o>r?o-r:null;return{firstUserMessage:s||"",duration:c,copilotVersion:a||null,selectedModel:i||null,hasSessionEnd:l,lastEventTime:o,firstEventTime:r}}catch(n){return console.error(`Error reading session metadata from ${u}:`,n.message),{firstUserMessage:"",duration:null,copilotVersion:null,selectedModel:null,hasSessionEnd:!1,lastEventTime:null}}}async function Hs(u,e=200){try{let n=Z.createReadStream(u,{encoding:"utf-8"}),t=X.createInterface({input:n,crlfDelay:1/0});for await(let s of t)if(s.trim())try{let r=JSON.parse(s);if(r.type==="user.message"){let o=r.data?.message||r.data?.content||r.data?.text||"";if(o)return t.close(),n.destroy(),o.length>e?o.substring(0,e)+"...":o}}catch{}return""}catch{return""}}async function Js(u){try{let e=Z.createReadStream(u,{encoding:"utf-8"}),n=X.createInterface({input:e,crlfDelay:1/0}),t=null,s=null;for await(let r of n)if(r.trim())try{let o=JSON.parse(r);if(o.timestamp){let a=new Date(o.timestamp).getTime();t||(t=a),s=a}}catch{}return t&&s&&s>=t?s-t:null}catch(e){return console.error(`Error calculating session duration for ${u}:`,e.message),null}}async function Gs(u){try{let e=Z.createReadStream(u,{encoding:"utf-8"}),n=X.createInterface({input:e,crlfDelay:1/0}),t=null,s=null;for await(let r of n)if(r.trim())try{let o=JSON.parse(r);if(o.type==="session.start"&&o.data&&(t=o.data.copilotVersion||null,s=o.data.selectedModel||null,s))return n.close(),e.destroy(),{copilotVersion:t,selectedModel:s};if(!s&&o.type==="session.model_change"&&o.data)return s=o.data.newModel||null,n.close(),e.destroy(),{copilotVersion:t,selectedModel:s}}catch{}return{copilotVersion:t,selectedModel:s}}catch(e){return console.error(`Error reading session metadata from ${u}:`,e.message),{copilotVersion:null,selectedModel:null}}}function Ks(u){return u===".DS_Store"||u.startsWith(".")}pt.exports={fileExists:Vs,countLines:Bs,parseYAML:Us,getFirstUserMessage:Hs,getSessionDuration:Js,getSessionMetadata:Gs,getSessionMetadataOptimized:Ws,shouldSkipEntry:Ks}});var ft=w((Sr,mt)=>{var he=class{constructor(){this._adapters=new Map}register(e){if(this._adapters.has(e.type))throw new Error(`Adapter already registered for type: ${e.type}`);this._adapters.set(e.type,e)}get(e){return this._adapters.get(e)||null}all(){return Array.from(this._adapters.values())}types(){return Array.from(this._adapters.keys())}get size(){return this._adapters.size}};mt.exports=he});var U=w((wr,ht)=>{var gt=require("fs"),Ys=require("readline"),ye=class{get type(){throw new Error("BaseSourceAdapter: type getter must be implemented")}get displayName(){throw new Error("BaseSourceAdapter: displayName getter must be implemented")}get badgeClass(){return`source-${this.type}`}get envVar(){}get displayMetadata(){return{name:this.displayName,badgeClass:this.badgeClass}}getDefaultDir(){throw new Error("BaseSourceAdapter: getDefaultDir() must be implemented")}async resolveDir(){return this.envVar&&process.env[this.envVar]?process.env[this.envVar]:this.getDefaultDir()}async scanEntries(e){throw new Error("BaseSourceAdapter: scanEntries() must be implemented")}async findById(e,n){throw new Error("BaseSourceAdapter: findById() must be implemented")}async resolveEventsFile(e,n){throw new Error("BaseSourceAdapter: resolveEventsFile() must be implemented")}async readJsonlEvents(e){if(!e)return[];try{await gt.promises.access(e);let n=gt.createReadStream(e,{encoding:"utf-8"}),t=Ys.createInterface({input:n,crlfDelay:1/0}),s=0,r=[];for await(let o of t){let a=o.trim();if(a)try{let i=JSON.parse(a);i._fileIndex=s,r.push(i)}catch(i){console.error(`Error parsing line ${s+1} in ${e}:`,i.message)}s++}return r}catch(n){return console.error("Error reading main events file:",n),[]}}async readEvents(e,n){return null}get hasCustomPipeline(){return!1}normalizeEvent(e){return e}matchToolCalls(e){}expandToTimelineFormat(e){return e}async mergeSubAgentEvents(e,n,t,s){}buildTimeline(e,n){return{turns:[],summary:{}}}async findSessionLocation(e,n){return null}async resolveExportPath(e,n){return null}};ht.exports=ye});var Q=w((_r,yt)=>{var Zs=require("path"),Se=class u{constructor(e,n,t={}){this.id=e,this.type=n,this.source=t.source||"copilot",this.directory=t.directory||null,this.filePath=t.filePath||null,this.workspace=t.workspace||{},this.createdAt=t.createdAt,this.updatedAt=t.updatedAt,this.summary=t.summary||(n==="file"?"Legacy session":"No summary"),this.hasEvents=t.hasEvents||!1,this.eventCount=t.eventCount||0,this.duration=t.duration||null,this.isImported=t.isImported||!1,this.hasInsight=t.hasInsight||!1,this.copilotVersion=t.copilotVersion||null,this.selectedModel=t.selectedModel||null,this.sessionStatus=t.sessionStatus||"completed"}static fromDirectory(e,n,t,s,r,o,a,i,l,c,d){let p=s?.created_at?new Date(s.created_at):s?.startTime?new Date(s.startTime):t.birthtime,m=s?.updated_at?new Date(s.updated_at):s?.endTime?new Date(s.endTime):t.mtime;return new u(n,"directory",{directory:e,workspace:s,createdAt:p,updatedAt:m,summary:s?.summary||"No summary",hasEvents:r>0,eventCount:r,duration:o,isImported:a,hasInsight:i,copilotVersion:l,selectedModel:c,sessionStatus:d})}static fromFile(e,n,t,s,r,o,a,i,l){return new u(n,"file",{filePath:e,directory:Zs.dirname(e),createdAt:t.birthtime,updatedAt:t.mtime,summary:r||"Legacy session",hasEvents:!0,eventCount:s,duration:o,isImported:!1,hasInsight:!1,copilotVersion:a,selectedModel:i,sessionStatus:l})}toJSON(){let e=this._getSourceDisplayMetadata(this.source);return{id:this.id,type:this.type,source:this.source,sourceName:e.name,sourceBadgeClass:e.badgeClass,directory:this.directory,workspace:this.workspace,createdAt:this.createdAt,updatedAt:this.updatedAt,summary:this.summary,hasEvents:this.hasEvents,eventCount:this.eventCount,duration:this.duration,isImported:this.isImported,hasInsight:this.hasInsight,copilotVersion:this.copilotVersion,selectedModel:this.selectedModel,sessionStatus:this.sessionStatus}}_getSourceDisplayMetadata(e){try{let{registry:t}=ce(),s=t.get(e);if(s)return s.displayMetadata}catch{}return{copilot:{name:"Copilot CLI",badgeClass:"source-copilot"},claude:{name:"Claude",badgeClass:"source-claude"},"pi-mono":{name:"Pi",badgeClass:"source-pi-mono"},vscode:{name:"Copilot Chat",badgeClass:"source-vscode"}}[e]||{name:e,badgeClass:"source-unknown"}}};yt.exports=Se});var we=w((Ir,St)=>{var Xs=require("fs"),Qs=require("readline");function en(u){return new Promise((e,n)=>{let t=Xs.createReadStream(u,{encoding:"utf-8"}),s=Qs.createInterface({input:t,crlfDelay:1/0}),r=!1;s.on("line",o=>{r||(r=!0,s.close(),e(o.trim()))}),s.on("close",()=>{r||e(null)}),s.on("error",o=>{r||(r=!0,n(o))}),t.on("error",o=>{r||(r=!0,s.close(),n(o))})})}function tn(u){return u.hasSessionEnd?"completed":u.lastEventTime!==null&&u.lastEventTime!==void 0&&Date.now()-u.lastEventTime<3e5?"wip":"completed"}St.exports={readFirstLine:en,computeSessionStatus:tn}});var bt=w((Tr,Et)=>{var M=require("path"),sn=require("os"),ee=require("fs").promises,nn=U(),wt=Q(),{fileExists:te,countLines:_t,parseYAML:rn,getSessionMetadataOptimized:It,shouldSkipEntry:on}=B(),{computeSessionStatus:Tt}=we(),_e=class extends nn{get type(){return"copilot"}get displayName(){return"Copilot CLI"}get envVar(){return"COPILOT_SESSION_DIR"}getDefaultDir(){return process.env.SESSION_DIR||M.join(sn.homedir(),".copilot","session-state")}async scanEntries(e){let t=(await ee.readdir(e)).filter(r=>!on(r)).map(async r=>{let o=M.join(e,r),a=await ee.stat(o);return a.isDirectory()?this._createDirectorySession(r,o,a):r.endsWith(".jsonl")?this._createFileSession(r,o,a):null});return(await Promise.allSettled(t)).filter(r=>r.status==="fulfilled"&&r.value!==null&&r.value!==void 0).map(r=>r.value)}async findById(e,n){try{let t=M.join(n,e),s=await ee.stat(t);if(s.isDirectory())return await this._createDirectorySession(e,t,s)}catch{}try{let t=M.join(n,`${e}.jsonl`),s=await ee.stat(t);if(s.isFile())return await this._createFileSession(`${e}.jsonl`,t,s)}catch{}return null}async resolveEventsFile(e,n){let t=e.id,s=M.join(n,t);try{return(await ee.stat(s)).isDirectory()?M.join(s,"events.jsonl"):M.join(n,`${t}.jsonl`)}catch{return M.join(n,`${t}.jsonl`)}}async readEvents(e,n){let t=await this.resolveEventsFile(e,n);return this.readJsonlEvents(t)}async _createDirectorySession(e,n,t){let s=M.join(n,"workspace.yaml"),r=M.join(n,"events.jsonl"),o=M.join(n,".imported"),a=M.join(n,`${e}.agent-review.md`),i=await te(s)?await rn(s):{summary:e,repo:"unknown"},l=await te(r)?await _t(r):0,c=await te(o),d=await te(a),p=null,m=null,g=null,f="completed";if(await te(r)){let S=await It(r);if(p=S.duration,m=S.copilotVersion,g=S.selectedModel,f=Tt(S),!i.summary&&S.firstUserMessage&&(i.summary=S.firstUserMessage),S.lastEventTime){let T=new Date(S.lastEventTime).getTime(),v=new Date(t.mtime).getTime();T>v&&(t={...t,mtime:new Date(T)})}}let y=wt.fromDirectory(n,e,t,i,l,p,c,d,m,g,f);return y.source="copilot",y}async _createFileSession(e,n,t){let s=e.replace(".jsonl",""),r=await _t(n),o=await It(n),a=Tt(o),i=wt.fromFile(n,s,t,r,o.firstUserMessage,o.duration,o.copilotVersion,o.selectedModel,a);return i.source="copilot",i}};Et.exports=_e});var W=w((Er,vt)=>{var Ie=class{canParse(e){throw new Error("canParse() must be implemented")}parse(e){throw new Error("parse() must be implemented")}getMetadata(e){throw new Error("getMetadata() must be implemented")}extractTurns(e){throw new Error("extractTurns() must be implemented")}extractToolCalls(e){throw new Error("extractToolCalls() must be implemented")}};vt.exports=Ie});var Ee=w((br,xt)=>{var an=W(),Te=class extends an{canParse(e){if(!e||e.length===0)return!1;let n=["session.start","user.message","assistant.turn_start","assistant.message","tool.execution_start"];return e.some(t=>t.type&&n.some(s=>t.type.startsWith(s)))}parse(e){return{metadata:this.getMetadata(e),turns:this.extractTurns(e),toolCalls:this.extractToolCalls(e),allEvents:e}}getMetadata(e){let n=e.find(s=>s.type==="session.start");if(!n)return null;let t=n.data||{};return{sessionId:t.sessionId,startTime:t.startTime,model:t.selectedModel,version:t.copilotVersion,producer:t.producer,cwd:t.context?.cwd,gitRoot:t.context?.gitRoot,branch:t.context?.branch,repository:t.context?.repository}}extractTurns(e){let n=[],t=null;for(let s of e)if(s.type==="user.message")t&&n.push(t),t={turnId:s.id,userMessage:{id:s.id,content:s.data?.content||"",transformedContent:s.data?.transformedContent,timestamp:s.timestamp},assistantMessages:[],toolCalls:[]};else if(s.type==="assistant.message"&&t)t.assistantMessages.push({id:s.id,messageId:s.data?.messageId,content:s.data?.content||"",toolRequests:s.data?.toolRequests||[],reasoningText:s.data?.reasoningText,timestamp:s.timestamp});else if(s.type.startsWith("tool.execution_")&&t){let r=s.data?.toolCallId,o=t.toolCalls.find(a=>a.toolCallId===r);o||(o={toolCallId:r,events:[]},t.toolCalls.push(o)),o.events.push(s),s.type==="tool.execution_start"?(o.name=s.data?.toolName,o.arguments=s.data?.arguments):s.type==="tool.execution_complete"&&(o.result=s.data?.result,o.exitCode=s.data?.exitCode)}return t&&n.push(t),n}extractToolCalls(e){let n=[],t=new Map;for(let s of e)if(s.type==="tool.execution_start"){let r=s.data?.toolCallId;t.set(r,{toolCallId:r,name:s.data?.toolName,arguments:s.data?.arguments,startEvent:s,completeEvent:null})}else if(s.type==="tool.execution_complete"){let r=s.data?.toolCallId,o=t.get(r);o&&(o.completeEvent=s,o.result=s.data?.result,o.exitCode=s.data?.exitCode,n.push(o))}return n}};xt.exports=Te});var ve=w((vr,jt)=>{var ln=W(),be=class extends ln{canParse(e){return!e||e.length===0?!1:e.some(n=>n.type&&["user","assistant"].includes(n.type)&&n.uuid&&Object.prototype.hasOwnProperty.call(n,"parentUuid")&&n.sessionId)}parse(e){return{metadata:this.getMetadata(e),turns:this.extractTurns(e),toolCalls:this.extractToolCalls(e),allEvents:e}}getMetadata(e){let n=e.find(r=>r.type==="user");if(!n)return null;let s=e.find(r=>r.type==="assistant"&&r.message?.model)?.message?.model||"unknown";return{sessionId:n.sessionId,startTime:n.timestamp,model:s,version:n.version,producer:"claude-code",cwd:n.cwd,gitRoot:null,branch:n.gitBranch,repository:null}}extractTurns(e){let n=[],t=e.filter(o=>["user","assistant"].includes(o.type)&&o.type!=="file-history-snapshot"&&o.type!=="queue-operation"),s=new Map;for(let o of t)s.set(o.uuid,o);let r=t.filter(o=>o.type==="user"&&(!o.parentUuid||!s.has(o.parentUuid)));for(let o of r){let a={turnId:o.uuid,userMessage:{id:o.uuid,content:this._extractMessageContent(o.message),timestamp:o.timestamp},assistantMessages:[],toolCalls:[]};this._collectAssistantResponses(o.uuid,s,a),n.push(a)}return n}_collectAssistantResponses(e,n,t){for(let[s,r]of n.entries())if(r.parentUuid===e&&r.type==="assistant"){let o={id:r.uuid,messageId:r.message?.id,content:this._extractMessageContent(r.message),model:r.message?.model,timestamp:r.timestamp},a=this._extractToolUse(r.message);a.length>0&&(o.toolRequests=a,t.toolCalls.push(...a.map(i=>({toolCallId:i.id,name:i.name,arguments:i.input,parentUuid:r.uuid})))),t.assistantMessages.push(o),this._collectAssistantResponses(r.uuid,n,t)}}_extractMessageContent(e){return!e||!e.content?"":typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.filter(n=>n.type==="text").map(n=>n.text).join(`
|
|
3
|
-
`):""}_extractToolUse(e){return!e||!e.content||!Array.isArray(e.content)?[]:e.content.filter(
|
|
4
|
-
`);break}case"markdownContent":{let
|
|
5
|
-
`);break}case void 0:case null:{let
|
|
6
|
-
`):e.generatedTitle||null}else
|
|
7
|
-
`).filter(y=>y.trim()).map(y=>{try{return JSON.parse(y)}catch{return null}}).filter(y=>y!==null),c=l.some(y=>y.type==="assistant"||y.type==="user"),
|
|
8
|
-
`).filter(
|
|
9
|
-
`).filter(o=>o.trim()),r=[];for(let o=0;o<s.length;o++)try{r.push(JSON.parse(s[o]))}catch(a){return console.warn(`[VSCode parse] Failed to parse ${n} line ${o+1}: ${a.message}`),null}return r.length===0?null:this._parser.canParse(r)?{sessionJson:this._parser.replayMutations(r),parsed:this._parser.parseJsonl(r)}:r.length===1&&r[0]&&typeof r[0]=="object"?{sessionJson:r[0],parsed:this._parser.parseVsCode(r[0])}:(console.warn(`[VSCode parse] Unsupported session format in ${n}`),null)}_parseJsonl(e,n="unknown"){return this._parseSessionContent(e,n)?.sessionJson||null}async _applyFileMtimeFallback(e,n){if(!e.length)return e;try{let t=await k.stat(n),s=new Date(t.mtime).toISOString(),r=e[e.length-1];if(!r?.timestamp)return e;let o=new Date(r.timestamp).getTime();(new Date(s).getTime()-o)/1e3>10&&(r.timestamp=s)}catch(t){console.error("[VSCode] Error getting file mtime:",t)}return e}async _resolveWorkspacePath(e){try{let n=b.join(e,"workspace.json"),t=await k.readFile(n,"utf-8"),s=JSON.parse(t);if(s.folder)return Ut(s.folder);if(s.workspace){let r=Ut(s.workspace);try{let o=await k.readFile(r,"utf-8"),a=JSON.parse(o);if(Array.isArray(a.folders)&&a.folders.length>0){let i=b.dirname(r);return b.resolve(i,a.folders[0].path)}}catch{}}}catch{}return null}_buildSession(e,n,t,s,r,o){let a=n[0],i=n[n.length-1],l=t.creationDate?new Date(t.creationDate):a.timestamp?new Date(a.timestamp):s.birthtime,c=i.timestamp?new Date(i.timestamp):null,d=t.lastMessageDate?new Date(t.lastMessageDate):c||s.mtime,m=this._extractLastTerminalTimestamp(n)||c||d,g=Date.now()-m.getTime()<900*1e3,f=this._extractUserText(a.message);return new bn(e,"file",{source:"vscode",filePath:s.filePath,directory:b.dirname(s.filePath),createdAt:l,updatedAt:m,summary:f?f.slice(0,120):`VSCode chat (${n.length} requests)`,hasEvents:!0,eventCount:n.reduce((y,S)=>y+(S.response||[]).length,0)+n.length*2+1,duration:m.getTime()-l.getTime(),sessionStatus:g?"wip":"completed",selectedModel:a.modelId||null,copilotVersion:a.agent?.extensionVersion||null,workspace:{cwd:o,workspaceHash:r}})}_expandVsCodeEvents(e){let n=[],t=[],s=null,r=null,o=0,a=null,i=null,l=()=>{t.length!==0&&(n.push({type:"assistant.message",id:`vscode-tools-${o}`,timestamp:r,parentId:s,data:{message:"",content:"",tools:t,subAgentId:a,subAgentName:i},_synthetic:!0}),t=[],a=null,i=null)};for(let c=0;c<e.length;c++){let d=e[c];if(d.type==="tool.invocation"){let p=d.data?.subAgentId||null;t.length>0&&p!==a&&l(),t.length===0&&(s=d.parentId,r=d.timestamp,o=c,a=p,i=d.data?.subAgentName||null),d.data?.tool&&t.push(d.data.tool);continue}l(),n.push(d)}return l(),n}_expandVsCodeToTimelineFormat(e){let n=[];for(let t=0;t<e.length;t++){let s=e[t];n.push(s),!(s.type!=="assistant.message"||!Array.isArray(s.data?.tools)||s.data.tools.length===0)&&s.data.tools.forEach((r,o)=>{if(!r.id||!r.name)return;let a=r.startTime||s.timestamp,i=r.endTime||s.timestamp;n.push({type:"tool.execution_start",id:`${r.id}-start`,timestamp:a,parentId:s.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,arguments:r.input||{}},_synthetic:!0,_fileIndex:s._fileIndex?s._fileIndex+.1+o*.02:void 0}),n.push({type:"tool.execution_complete",id:`${r.id}-complete`,timestamp:i,parentId:r.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,result:r.result||null,error:r.error||(r.status==="error"?"Tool execution failed":null),isError:r.status==="error"},_synthetic:!0,_fileIndex:s._fileIndex?s._fileIndex+.15+o*.02:void 0})})}return n}_extractLastTerminalTimestamp(e){let n=0;function t(s){if(!(!s||typeof s!="object")){if(Array.isArray(s)){s.forEach(t);return}if(s.terminalCommandState&&typeof s.terminalCommandState.timestamp=="number"){let r=s.terminalCommandState.timestamp;r>1e12&&r<9999999999999&&r>n&&(n=r)}for(let r of Object.values(s))t(r)}}for(let s of e)t(s.response);return n>0?new Date(n):null}_extractUserText(e){return e?typeof e.text=="string"?e.text:Array.isArray(e.parts)?e.parts.filter(n=>n.kind==="text").map(n=>n.text||"").join(""):"":""}};Ht.exports=Oe});var ce=w((Nr,Kt)=>{var Gt=ft(),jn=U(),Cn=bt(),An=qt(),Dn=Bt(),kn=Jt(),ne=new Gt;ne.register(new Cn);ne.register(new An);ne.register(new Dn);ne.register(new kn);Kt.exports={registry:ne,AdapterRegistry:Gt,BaseSourceAdapter:jn}});var qe=w(($r,Yt)=>{var Mn=require("fs").promises,{shouldSkipEntry:Nn}=B(),{registry:$n}=ce(),Re=class{constructor(e){if(this.registry=$n,typeof e=="string")this.sources=[{type:"copilot",dir:e}];else if(Array.isArray(e))this.sources=e;else{this.sources=this.registry.all().map(n=>({type:n.type,dir:n.getDefaultDir()}));for(let n of this.sources){let t=this.registry.get(n.type);t&&t.envVar&&process.env[t.envVar]&&(n.dir=process.env[t.envVar]),n.type==="copilot"&&process.env.SESSION_DIR&&!process.env.COPILOT_SESSION_DIR&&(n.dir=process.env.SESSION_DIR)}}this._cache=new Map,this._cacheTTL=60*1e3,this._pendingScans=new Map}invalidateCache(e=null){e?(this._cache.delete(e),this._cache.delete(null)):this._cache.clear()}async findAll(e=null){let n=e||"__all__",t=this._cache.get(n);if(t&&Date.now()-t.timestamp<this._cacheTTL)return t.data;if(this._pendingScans.has(n))return this._pendingScans.get(n);let s=this._doFindAll(e).then(r=>(this._cache.set(n,{data:r,timestamp:Date.now()}),this._pendingScans.delete(n),r)).catch(r=>{throw this._pendingScans.delete(n),r});return this._pendingScans.set(n,s),s}async _doFindAll(e=null){let n=[],t=e?this.sources.filter(s=>s.type===e):this.sources;for(let s of t)try{let r=await this._scanSource(s);n.push(...r)}catch(r){console.error(`Error reading ${s.type} sessions from ${s.dir}:`,r.message)}return this._sortByUpdatedAt(this._deduplicateSessions(n))}async _scanSource(e){let n=this.registry.get(e.type);if(!n)return console.warn(`No adapter registered for source type: ${e.type}`),[];let t;if(e.dir?t=e.dir:t=await n.resolveDir(),!t)return console.warn(`No directory resolved for ${e.type}`),[];try{await Mn.access(t)}catch{return console.warn(`Source directory not found: ${t}`),[]}return n.scanEntries(t)}_deduplicateSessions(e){let n=new Map;for(let t of e){let s=n.get(t.id);(!s||t.updatedAt&&s.updatedAt&&new Date(t.updatedAt)>new Date(s.updatedAt))&&n.set(t.id,t)}return Array.from(n.values())}async findById(e){if(Nn(e))return null;for(let n of this.sources){let t=this.registry.get(n.type);if(!t)continue;let s;if(n.dir?s=n.dir:s=await t.resolveDir(),!s)continue;let r=await t.findById(e,s);if(r)return r}return null}_sortByUpdatedAt(e){return e.sort((n,t)=>new Date(t.createdAt)-new Date(n.createdAt))}};Yt.exports=Re});var Xt=w((Pr,Zt)=>{var Fe=class{normalizeEvents(e,n){return Array.isArray(e)?e.filter(t=>!t._isToolResultWrapper).map(t=>this.normalizeEvent(t,n)):(console.warn("[EventNormalizer] normalizeEvents: events is not an array",typeof e),[])}normalizeEvent(e,n){return!e||typeof e!="object"?(console.warn("[EventNormalizer] normalizeEvent: invalid event",e),e):this._isAssistantMessage(e)?this._normalizeAssistantMessage(e,n):this._isTimelineEvent(e)?this._normalizeTimelineEvent(e,n):e}_isAssistantMessage(e){return e.data?.tools&&Array.isArray(e.data.tools)&&e.data.tools.length>0?!0:e.type==="assistant.message"||e.type==="assistant"||e.type==="user.message"||e.type==="user"}_isTimelineEvent(e){return e.type?.startsWith("tool.")||e.type?.startsWith("subagent.")}_normalizeAssistantMessage(e,n){let t={...e};return e.data?.tools&&Array.isArray(e.data.tools)&&(t.data={...e.data,tools:e.data.tools.filter(s=>s.type!=="tool_result").map(s=>this._normalizeToolCall(s,n,e.timestamp))}),t}_normalizeToolCall(e,n,t){if(e.type==="tool_use"){let s=this._computeStatus(e),r=e._startTime||t,o=e._matched?e._endTime||t:null;return{type:"tool_use",id:e.id,name:e.name,startTime:r,endTime:o,status:s,input:e.input||{},result:e.result||null,error:e.error||null,metadata:{source:n,matched:e._matched,duration:this._computeDuration(r,o)}}}if(e.name&&e.status){let s=t,r=e.status==="success"?"completed":e.status,o=r==="completed"||r==="error"?t:null;return{id:e.id||this._generateToolId(),name:e.name,startTime:s,endTime:o,status:r,input:e.input||{},result:e.isError?null:e.result||null,error:e.isError?e.result:null,metadata:{source:n,duration:this._computeDuration(s,o)}}}return console.warn("[EventNormalizer] Unknown tool format, applying fallback normalization",e),{id:e.id||this._generateToolId(),name:e.name||"unknown",startTime:t,endTime:null,status:"running",input:e.input||{},result:null,error:null,metadata:{source:n,fallback:!0}}}_computeStatus(e){return e.error?"error":e.result!==void 0&&e.result!==null&&e.result!==""?"completed":e._matched===!1?"running":e._matched?"completed":"running"}_computeDuration(e,n){if(!(!e||!n))try{let t=new Date(e),s=new Date(n);if(isNaN(t.getTime())||isNaN(s.getTime()))return;let r=s.getTime()-t.getTime();return r>=0?r:void 0}catch{return}}_generateToolId(){return`tool-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}_normalizeTimelineEvent(e){return e.type==="tool.execution_start"||e.type==="tool.execution_complete"?{...e,data:{...e.data,toolCallId:e.data?.toolCallId||e.data?.id,toolName:e.data?.toolName||e.data?.tool||e.data?.name,...e.data}}:(e.type?.startsWith("subagent."),e)}};Zt.exports=Fe});var ze=w((Or,ts)=>{var re=require("fs"),H=require("path"),Pn=require("readline"),{isValidSessionId:Qt,buildMetadata:On}=V(),es=qe(),Rn=Xt(),Le=class{constructor(e){e?(this.SESSION_DIR=e,this.sessionRepository=new es(e)):this.sessionRepository=new es,this.eventNormalizer=new Rn}async getAllSessions(e=null){return(await this.sessionRepository.findAll(e)).map(t=>t.toJSON())}async getPaginatedSessions(e=1,n=20,t=null){let r=(await this.sessionRepository.findAll(t)).map(l=>l.toJSON()),o=(e-1)*n,a=o+n;return{sessions:r.slice(o,a),totalSessions:r.length,currentPage:e,totalPages:Math.ceil(r.length/n),hasNextPage:a<r.length,hasPrevPage:e>1}}async getSessionById(e){return Qt(e)?(await this.getAllSessions()).find(t=>t.id===e):null}async getSessionEvents(e,n=null){if(!Qt(e))return n?{events:[],total:0}:[];let t=await this.sessionRepository.findById(e);if(!t)return n?{events:[],total:0}:[];let s=this._getSourceAdapter(t.source),o=this.sessionRepository.sources.find(l=>l.type===t.source)?.dir||null;!o&&s&&(o=await s.resolveDir()),this.SESSION_DIR&&t.source==="copilot"&&(o=this.SESSION_DIR);let a=s&&!s.hasCustomPipeline?await s.resolveEventsFile(t,o):null,i=[];if(s?i=await s.readEvents(t,o)||[]:console.warn(`SessionService.getSessionEvents: No adapter found for source '${t.source}'. Returning no events.`),i.length>0&&(t.source==="claude"&&t.type==="directory"?i=i.filter(c=>c._subagent):i=i.filter(c=>!c._subagent)),i.sort((l,c)=>{let d=l.timestamp?new Date(l.timestamp).getTime():0,p=c.timestamp?new Date(c.timestamp).getTime():0;return d!==p?d-p:(l._fileIndex??0)-(c._fileIndex??0)}),i=i.map(l=>this._normalizeEvent(l,t.source)),s&&!s.hasCustomPipeline&&await this._mergeSubAgentEvents(i,a,e,t.source),s&&!s.hasCustomPipeline&&t.source==="copilot"?(this._matchCopilotToolCalls(i),this._mergeHookEvents(i),i=this._expandCopilotToTimelineFormat(i)):s&&!s.hasCustomPipeline&&t.source==="claude"?(this._matchClaudeToolResults(i),i=this._expandClaudeToTimelineFormat(i)):s&&!s.hasCustomPipeline&&t.source==="pi-mono"&&this._mergePiMonoToolResults(i),i=i.filter(l=>l.timestamp||l.snapshot?.timestamp?!0:(console.warn("[SessionService] Filtered event without timestamp:",l.type,l.id||l._fileIndex),!1)),i.forEach(l=>{l._fileIndex===999999&&l.timestamp&&delete l._fileIndex}),i=this.eventNormalizer.normalizeEvents(i,t.source),n&&typeof n.limit=="number"&&typeof n.offset=="number"){let l=i.length;return{events:i.slice(n.offset,n.offset+n.limit),total:l}}return i}async _mergeSubAgentEvents(e,n,t,s){let r;if(s==="claude"){let o=this.sessionRepository.sources.find(a=>a.type==="claude");if(!o)return;try{let a=await re.promises.readdir(o.dir);for(let i of a){let l=H.join(o.dir,i,t,"subagents");try{if((await re.promises.stat(l)).isDirectory()){r=l;break}}catch{}}}catch(a){console.error("Error searching Claude subagents:",a);return}}else if(s==="copilot"&&n){let o=H.dirname(n);H.basename(n)==="events.jsonl"?r=H.join(o,"subagents"):r=H.join(o,t,"subagents")}if(r){try{if(!(await re.promises.stat(r)).isDirectory())return}catch{return}try{let a=(await re.promises.readdir(r)).filter(i=>i.startsWith("agent-")&&i.endsWith(".jsonl"));if(a.length===0)return;for(let i of a){let l=i.replace(".jsonl",""),c=H.join(r,i);try{let d=re.createReadStream(c,{encoding:"utf-8"}),p=Pn.createInterface({input:d,crlfDelay:1/0}),m=[];for await(let x of p){let P=x.trim();P&&m.push(P)}if(m.length===0)continue;let g=l.replace("agent-",""),f=g.toUpperCase(),y=`Sub-agent ${l}`;try{let x=JSON.parse(m[0]);if(x.agentId&&(g=x.agentId,f=`agent-${x.agentId}`),x.message?.content){let P=typeof x.message.content=="string"?x.message.content:JSON.stringify(x.message.content);y=P.length>100?P.slice(0,100)+"...":P}}catch{}let S=m.map((x,P)=>{try{let Y=JSON.parse(x);return Y._fileIndex=1e6+P,Y._subagent={id:l,name:g},Y}catch(Y){return console.error(`Error parsing sub-agent ${l} line ${P+1}:`,Y.message),null}}).filter(x=>x!==null);if(S.length===0)continue;let T=S.map(x=>this._normalizeEvent(x,s)),v=T[0],j=T[T.length-1],L=v.timestamp||new Date().toISOString(),pe=j.timestamp||new Date().toISOString(),me={type:"subagent.started",id:`${l}-start`,timestamp:L,_fileIndex:v._fileIndex-1,_subagent:{id:l,name:g},data:{toolCallId:l,agentName:g,agentDisplayName:f,agentDescription:y}},tt={type:"subagent.completed",id:`${l}-end`,timestamp:pe,_fileIndex:j._fileIndex+1,_subagent:{id:l,name:g},data:{toolCallId:l,result:`Sub-agent ${f} completed`}};e.push(me,...T,tt)}catch(d){console.error(`Error reading sub-agent ${l}:`,d)}}e.sort((i,l)=>{let c=i.timestamp?new Date(i.timestamp).getTime():0,d=l.timestamp?new Date(l.timestamp).getTime():0;return c!==d?c-d:i._fileIndex-l._fileIndex})}catch(o){console.error("Error processing sub-agents:",o)}}}_matchClaudeToolResults(e){let n=new Map;e.forEach(t=>{t.data?.tools&&t.data.tools.forEach(s=>{s.type==="tool_result"&&(s.tool_use_id?n.set(s.tool_use_id,s):console.warn("[sessionService] tool_result missing tool_use_id:",s))})}),e.forEach(t=>{t.type==="user"&&Array.isArray(t.message?.content)&&t.message.content.length>0&&t.message.content.every(r=>r?.type==="tool_result")&&(t._isToolResultWrapper=!0)}),e.forEach(t=>{t.data?.tools&&(t.data.tools=t.data.tools.map(s=>{if(s.type==="tool_use"){let r=n.get(s.id);return r?{...s,result:r.content,_matched:!0}:{...s,_matched:!1}}return s}),t.type==="assistant"||t.type==="assistant.message"?t.data.tools=t.data.tools.filter(s=>s.type!=="tool_result"):(t.type==="user"||t.type==="user.message")&&t.data.tools.length>0&&t.data.tools.every(r=>r.type==="tool_result")&&(t._isToolResultWrapper=!0))})}_mergePiMonoToolResults(e){let n=new Set;e.forEach(s=>{if(s.type==="assistant.message"&&s.data.tools&&s.data.tools.length>0){let r=s.data.tools,o=[],a=s.id,i=!0;for(;i&&o.length<r.length;){i=!1;for(let l of e)if(l.type==="message"&&l.data.role==="toolResult"&&l.parentId===a&&!o.includes(l)){o.push(l),a=l.id,i=!0;break}}o.forEach((l,c)=>{if(c<r.length){let d=r[c];d.result=l.data.result,d.resultId=l.id,d.status="completed",n.add(l.id)}})}});let t=e.length;for(let s=e.length-1;s>=0;s--)e[s].type==="message"&&e[s].data.role==="toolResult"&&n.has(e[s].id)&&e.splice(s,1);n.size>0&&console.log(`[PI-MONO] Merged ${n.size} toolResult events into assistant messages (${t} \u2192 ${e.length} events)`)}_matchPiMonoToolResults_OLD(e){let n=new Set;e.forEach(s=>{if(s.type==="assistant.message"&&s.data.tools&&s.data.tools.length>0){let r=s.data.tools,o=[],a=s.id,i=!0;for(;i&&o.length<r.length;){i=!1;for(let l of e)if(l.type==="tool.result"&&l.parentId===a&&!o.includes(l)){o.push(l),a=l.id,i=!0;break}}o.forEach((l,c)=>{if(c<r.length){let d=r[c];d.status="completed",d._matched=!0,d.result=l.data.result,d.resultId=l.id,n.add(l.id)}})}});let t=e.length;for(let s=e.length-1;s>=0;s--)e[s].type==="tool.result"&&n.has(e[s].id)&&e.splice(s,1);n.size>0&&console.log(`[PI-MONO] Removed ${n.size} matched tool.result events (${t} \u2192 ${e.length} events)`)}_mergeHookEvents(e){let n=new Map;for(let t=0;t<e.length;t++){let s=e[t],r=s.data?.hookInvocationId;if(r){if(s.type==="hook.start")n.set(r,t);else if(s.type==="hook.end"){let o=n.get(r);if(o!==void 0){let a=e[o],i=s.data?.success!==!1;if(a.data.hookSuccess=i,a.data.hookError=s.data?.error||null,a.timestamp&&s.timestamp){let l=new Date(s.timestamp)-new Date(a.timestamp);a.data.hookDurationMs=l;let c=l<1e3?`${l}ms`:`${(l/1e3).toFixed(2)}s`;a.data.message&&(a.data.message+=`
|
|
10
|
-
**Duration:** ${c}`)}
|
|
1
|
+
var w=(p,e)=>()=>(e||p((e={exports:{}}).exports,e),e.exports);var U=w((br,dt)=>{var ge=require("applicationinsights"),ie=require("fs"),le=require("path"),$s=require("crypto"),ct=require("os");function Os(){let p=le.join(ct.homedir(),".copilot-session-viewer"),e=le.join(p,"analytics-id");try{return ie.readFileSync(e,"utf8").trim()}catch{let s=$s.randomUUID();try{ie.mkdirSync(p,{recursive:!0}),ie.writeFileSync(e,s)}catch{}return s}}function Ps(){try{let p=[le.join(__dirname,"..","package.json"),le.join(__dirname,"package.json")];for(let e of p)try{return JSON.parse(ie.readFileSync(e,"utf8")).version}catch{}}catch{}return"unknown"}var ut=process.env.DISABLE_TELEMETRY==="true",Rs="InstrumentationKey=39f4fbf1-d82f-42c3-b4ef-ea92a1fd82cb;IngestionEndpoint=https://eastus-8.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/;ApplicationId=7d4bb432-f2f5-4526-a5e6-31901e5a2db2",E=null;if(ut)E=lt(),console.log("\u{1F4CA} Telemetry disabled (DISABLE_TELEMETRY=true)");else try{let p=process.env.APPLICATIONINSIGHTS_CONNECTION_STRING||Rs;ge.setup(p).setAutoDependencyCorrelation(!0).setAutoCollectRequests(!0).setAutoCollectPerformance(!0,!0).setAutoCollectExceptions(!0).setAutoCollectDependencies(!0).setAutoCollectConsole(!1).setUseDiskRetryCaching(!0).setSendLiveMetrics(!1).setDistributedTracingMode(ge.DistributedTracingModes.AI_AND_W3C).start(),E=ge.defaultClient;let e=Ps(),s=Os();E.context.tags[E.context.keys.cloudRole]="copilot-session-viewer",E.context.tags[E.context.keys.cloudRoleInstance]=ct.hostname(),E.context.tags[E.context.keys.applicationVersion]=e,E.context.tags[E.context.keys.userId]=s,E.addTelemetryProcessor(t=>(t.data.baseData.properties=t.data.baseData.properties||{},t.data.baseData.properties.appVersion=e,!0)),console.log("\u2705 Application Insights telemetry initialized")}catch(p){console.error("\u274C Failed to initialize Application Insights:",p.message),E=lt()}function lt(){return{trackEvent:()=>{},trackMetric:()=>{},trackException:()=>{},trackTrace:()=>{},trackDependency:()=>{},trackRequest:()=>{},flush:p=>{p&&p()}}}function qs(p,e={}){E&&E.trackEvent&&E.trackEvent({name:p,properties:e})}function Fs(p,e,s={}){E&&E.trackMetric&&E.trackMetric({name:p,value:e,properties:s})}function Us(p,e={}){E&&E.trackException&&E.trackException({exception:p,properties:e})}function Ls(){return new Promise(p=>{E&&E.flush?E.flush({callback:()=>p()}):p()})}dt.exports={client:E,trackEvent:qs,trackMetric:Fs,trackException:Us,flush:Ls,isEnabled:!ut}});var L=w((Cr,pt)=>{pt.exports={PORT:process.env.PORT||3838,NODE_ENV:process.env.NODE_ENV||"production",LOG_LEVEL:process.env.LOG_LEVEL||(process.env.NODE_ENV==="development"?"DEBUG":"INFO"),INSIGHT_TIMEOUT_MS:300*1e3,INSIGHT_CACHE_TTL_MS:1440*60*1e3,MAX_UPLOAD_SIZE:10*1024*1024,SESSION_CACHE_TTL_MS:30*1e3,RATE_LIMIT_WINDOW_MS:900*1e3,RATE_LIMIT_MAX_REQUESTS:15,REQUEST_TIMEOUT_MS:30*1e3}});var gt=w((vr,ft)=>{var he=L(),{trackException:zs,isEnabled:mt}=U(),Vs=(p,e,s)=>{p.setTimeout(he.REQUEST_TIMEOUT_MS),s()},Bs=(p,e,s)=>{e.locals.telemetryEnabled=mt,e.locals.telemetryConnectionString=mt?process.env.APPLICATIONINSIGHTS_CONNECTION_STRING||"InstrumentationKey=39f4fbf1-d82f-42c3-b4ef-ea92a1fd82cb;IngestionEndpoint=https://eastus-8.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/;ApplicationId=7d4bb432-f2f5-4526-a5e6-31901e5a2db2":null,s()},Ws=(p,e,s)=>{if(he.NODE_ENV==="development"){let t=["http://localhost:3838","http://127.0.0.1:3838"],n=p.headers.origin;t.includes(n)&&(e.header("Access-Control-Allow-Origin",n),e.header("Access-Control-Allow-Methods","GET, POST, DELETE, OPTIONS"),e.header("Access-Control-Allow-Headers","Content-Type"))}s()},Hs=(p,e,s,t)=>{console.error("Unhandled error:",p.stack),zs(p,{url:e.url,method:e.method,statusCode:(p.status||500).toString(),userAgent:e.headers&&e.headers["user-agent"]||"unknown"});let n=p.status||500,r=he.NODE_ENV==="development",a=r?p.message:"Internal server error";s.status(n).json({error:a,...r&&{stack:p.stack}})},Js=(p,e)=>{e.status(404).json({error:"Not found"})};ft.exports={requestTimeout:Vs,developmentCors:Ws,errorHandler:Hs,notFoundHandler:Js,telemetryLocals:Bs}});var z=w((xr,ht)=>{function Gs(p){let e=p.toJSON?p.toJSON():{};return{type:p.type,source:p.source,sourceName:e.sourceName||p.source,sourceBadgeClass:e.sourceBadgeClass||"source-unknown",summary:p.summary,model:p.selectedModel||p.model,repo:p.workspace?.repository,branch:p.workspace?.branch,cwd:p.workspace?.cwd,created:p.createdAt,updated:p.updatedAt,copilotVersion:p.copilotVersion,modernizeVersion:p.modernizeVersion,sessionStatus:p.sessionStatus}}function Ks(p){return typeof p=="string"&&/^[a-zA-Z0-9_-]+$/.test(p)&&p.length<256}ht.exports={buildMetadata:Gs,isValidSessionId:Ks}});var V=w((jr,yt)=>{var ye=require("fs").promises,X=require("fs"),Q=require("readline"),Ys=require("js-yaml");async function Zs(p){try{return await ye.access(p),!0}catch{return!1}}async function Xs(p){try{let e=X.createReadStream(p,{encoding:"utf-8"}),s=Q.createInterface({input:e,crlfDelay:1/0}),t=0;for await(let n of s)n.trim()&&t++;return t}catch(e){return console.error(`Error counting lines in ${p}:`,e.message),0}}async function Qs(p){try{let e=await ye.readFile(p,"utf-8"),s=Ys.load(e);return s&&typeof s=="object"?s:{}}catch{try{let s=await ye.readFile(p,"utf-8"),t={};for(let n of s.split(`
|
|
2
|
+
`)){let r=n.trim();if(!r||r.startsWith("#"))continue;let a=r.indexOf(":");if(a<=0)continue;let o=r.slice(0,a).trim(),i=r.slice(a+1).trim();o&&(t[o]=i)}return t}catch(s){return console.error(`Error parsing YAML ${p}:`,s.message),{}}}}async function en(p,e=500){try{let s=X.createReadStream(p,{encoding:"utf-8"}),t=Q.createInterface({input:s,crlfDelay:1/0}),n="",r=null,a=null,o=null,i=null,l=!1;for await(let u of t)if(u.trim())try{let d=JSON.parse(u);if(d.timestamp){let f=new Date(d.timestamp).getTime();isNaN(f)||(r||(r=f),a=f)}if(!n&&d.type==="user.message"){let f=d.data?.message||d.data?.content||d.data?.text||"";f&&(n=f.length>e?f.substring(0,e)+"...":f)}d.type==="session.end"&&(l=!0),d.type==="session.start"&&d.data?.copilotVersion&&!o&&(o=d.data.copilotVersion),(d.type==="session.start"||d.type==="session.model_change")&&!i&&(d.data?.selectedModel?i=d.data.selectedModel:d.data?.newModel?i=d.data.newModel:d.data?.model&&(i=d.data.model))}catch{}t.close(),s.destroy();let c=r&&a&&a>r?a-r:null;return{firstUserMessage:n||"",duration:c,copilotVersion:o||null,selectedModel:i||null,hasSessionEnd:l,lastEventTime:a,firstEventTime:r}}catch(s){return console.error(`Error reading session metadata from ${p}:`,s.message),{firstUserMessage:"",duration:null,copilotVersion:null,selectedModel:null,hasSessionEnd:!1,lastEventTime:null}}}async function tn(p,e=200){try{let s=X.createReadStream(p,{encoding:"utf-8"}),t=Q.createInterface({input:s,crlfDelay:1/0});for await(let n of t)if(n.trim())try{let r=JSON.parse(n);if(r.type==="user.message"){let a=r.data?.message||r.data?.content||r.data?.text||"";if(a)return t.close(),s.destroy(),a.length>e?a.substring(0,e)+"...":a}}catch{}return""}catch{return""}}async function sn(p){try{let e=X.createReadStream(p,{encoding:"utf-8"}),s=Q.createInterface({input:e,crlfDelay:1/0}),t=null,n=null;for await(let r of s)if(r.trim())try{let a=JSON.parse(r);if(a.timestamp){let o=new Date(a.timestamp).getTime();t||(t=o),n=o}}catch{}return t&&n&&n>=t?n-t:null}catch(e){return console.error(`Error calculating session duration for ${p}:`,e.message),null}}async function nn(p){try{let e=X.createReadStream(p,{encoding:"utf-8"}),s=Q.createInterface({input:e,crlfDelay:1/0}),t=null,n=null;for await(let r of s)if(r.trim())try{let a=JSON.parse(r);if(a.type==="session.start"&&a.data&&(t=a.data.copilotVersion||null,n=a.data.selectedModel||null,n))return s.close(),e.destroy(),{copilotVersion:t,selectedModel:n};if(!n&&a.type==="session.model_change"&&a.data)return n=a.data.newModel||null,s.close(),e.destroy(),{copilotVersion:t,selectedModel:n}}catch{}return{copilotVersion:t,selectedModel:n}}catch(e){return console.error(`Error reading session metadata from ${p}:`,e.message),{copilotVersion:null,selectedModel:null}}}function rn(p){return p===".DS_Store"||p.startsWith(".")}yt.exports={fileExists:Zs,countLines:Xs,parseYAML:Qs,getFirstUserMessage:tn,getSessionDuration:sn,getSessionMetadata:nn,getSessionMetadataOptimized:en,shouldSkipEntry:rn}});var wt=w((Ar,St)=>{var Se=class{constructor(){this._adapters=new Map}register(e){if(this._adapters.has(e.type))throw new Error(`Adapter already registered for type: ${e.type}`);this._adapters.set(e.type,e)}get(e){return this._adapters.get(e)||null}all(){return Array.from(this._adapters.values())}types(){return Array.from(this._adapters.keys())}get size(){return this._adapters.size}};St.exports=Se});var B=w((Dr,It)=>{var _t=require("fs"),an=require("readline"),we=class{get type(){throw new Error("BaseSourceAdapter: type getter must be implemented")}get displayName(){throw new Error("BaseSourceAdapter: displayName getter must be implemented")}get badgeClass(){return`source-${this.type}`}get envVar(){}get displayMetadata(){return{name:this.displayName,badgeClass:this.badgeClass}}getDefaultDir(){throw new Error("BaseSourceAdapter: getDefaultDir() must be implemented")}async resolveDir(){return this.envVar&&process.env[this.envVar]?process.env[this.envVar]:this.getDefaultDir()}async scanEntries(e){throw new Error("BaseSourceAdapter: scanEntries() must be implemented")}async findById(e,s){throw new Error("BaseSourceAdapter: findById() must be implemented")}async resolveEventsFile(e,s){throw new Error("BaseSourceAdapter: resolveEventsFile() must be implemented")}async readJsonlEvents(e){if(!e)return[];try{await _t.promises.access(e);let s=_t.createReadStream(e,{encoding:"utf-8"}),t=an.createInterface({input:s,crlfDelay:1/0}),n=0,r=[];for await(let a of t){let o=a.trim();if(o)try{let i=JSON.parse(o);i._fileIndex=n,r.push(i)}catch(i){console.error(`Error parsing line ${n+1} in ${e}:`,i.message)}n++}return r}catch(s){return console.error("Error reading main events file:",s),[]}}async readEvents(e,s){return null}get hasCustomPipeline(){return!1}normalizeEvent(e){return e}matchToolCalls(e){}expandToTimelineFormat(e){return e}async mergeSubAgentEvents(e,s,t,n){}buildTimeline(e,s){return{turns:[],summary:{}}}async findSessionLocation(e,s){return null}async resolveExportPath(e,s){return null}};It.exports=we});var ee=w((kr,Tt)=>{var on=require("path"),_e=class p{constructor(e,s,t={}){this.id=e,this.type=s,this.source=t.source||"copilot",this.directory=t.directory||null,this.filePath=t.filePath||null,this.workspace=t.workspace||{},this.createdAt=t.createdAt,this.updatedAt=t.updatedAt,this.summary=t.summary||(s==="file"?"Legacy session":"No summary"),this.hasEvents=t.hasEvents||!1,this.eventCount=t.eventCount||0,this.duration=t.duration||null,this.isImported=t.isImported||!1,this.hasInsight=t.hasInsight||!1,this.copilotVersion=t.copilotVersion||null,this.modernizeVersion=t.modernizeVersion||null,this.selectedModel=t.selectedModel||null,this.sessionStatus=t.sessionStatus||"completed"}static fromDirectory(e,s,t,n,r,a,o,i,l,c,u){let d=n?.created_at?new Date(n.created_at):n?.startTime?new Date(n.startTime):t.birthtime||(t.birthtimeMs?new Date(t.birthtimeMs):void 0),f=n?.updated_at?new Date(n.updated_at):n?.endTime?new Date(n.endTime):t.mtime;return new p(s,"directory",{directory:e,workspace:n,createdAt:d,updatedAt:f,summary:n?.summary||"No summary",hasEvents:r>0,eventCount:r,duration:a,isImported:o,hasInsight:i,copilotVersion:l,selectedModel:c,sessionStatus:u})}static fromFile(e,s,t,n,r,a,o,i,l){return new p(s,"file",{filePath:e,directory:on.dirname(e),createdAt:t.birthtime||(t.birthtimeMs?new Date(t.birthtimeMs):void 0),updatedAt:t.mtime,summary:r||"Legacy session",hasEvents:!0,eventCount:n,duration:a,isImported:!1,hasInsight:!1,copilotVersion:o,selectedModel:i,sessionStatus:l})}toJSON(){let e=this._getSourceDisplayMetadata(this.source);return{id:this.id,type:this.type,source:this.source,sourceName:e.name,sourceBadgeClass:e.badgeClass,directory:this.directory,workspace:this.workspace,createdAt:this.createdAt,updatedAt:this.updatedAt,summary:this.summary,hasEvents:this.hasEvents,eventCount:this.eventCount,duration:this.duration,isImported:this.isImported,hasInsight:this.hasInsight,copilotVersion:this.copilotVersion,modernizeVersion:this.modernizeVersion,selectedModel:this.selectedModel,sessionStatus:this.sessionStatus}}_getSourceDisplayMetadata(e){try{let{registry:t}=ce(),n=t.get(e);if(n)return n.displayMetadata}catch{}return{copilot:{name:"Copilot CLI",badgeClass:"source-copilot"},claude:{name:"Claude",badgeClass:"source-claude"},"pi-mono":{name:"Pi",badgeClass:"source-pi-mono"},vscode:{name:"Copilot Chat",badgeClass:"source-vscode"}}[e]||{name:e,badgeClass:"source-unknown"}}};Tt.exports=_e});var Ie=w((Mr,Et)=>{var ln=require("fs"),cn=require("readline");function un(p){return new Promise((e,s)=>{let t=ln.createReadStream(p,{encoding:"utf-8"}),n=cn.createInterface({input:t,crlfDelay:1/0}),r=!1;n.on("line",a=>{r||(r=!0,n.close(),e(a.trim()))}),n.on("close",()=>{r||e(null)}),n.on("error",a=>{r||(r=!0,s(a))}),t.on("error",a=>{r||(r=!0,n.close(),s(a))})})}function dn(p){return p.hasSessionEnd?"completed":p.lastEventTime!==null&&p.lastEventTime!==void 0&&Date.now()-p.lastEventTime<3e5?"wip":"completed"}Et.exports={readFirstLine:un,computeSessionStatus:dn}});var Ee=w((Nr,jt)=>{var N=require("path"),pn=require("os"),te=require("fs").promises,mn=B(),bt=ee(),{fileExists:se,countLines:Ct,parseYAML:fn,getSessionMetadataOptimized:vt,shouldSkipEntry:gn}=V(),{computeSessionStatus:xt}=Ie(),Te=class extends mn{get type(){return"copilot"}get displayName(){return"Copilot CLI"}get envVar(){return"COPILOT_SESSION_DIR"}getDefaultDir(){return process.env.SESSION_DIR||N.join(pn.homedir(),".copilot","session-state")}async scanEntries(e){let t=(await te.readdir(e)).filter(r=>!gn(r)).map(async r=>{let a=N.join(e,r),o=await te.stat(a);return o.isDirectory()?this._createDirectorySession(r,a,o):r.endsWith(".jsonl")?this._createFileSession(r,a,o):null});return(await Promise.allSettled(t)).filter(r=>r.status==="fulfilled"&&r.value!==null&&r.value!==void 0).map(r=>r.value)}async findById(e,s){try{let t=N.join(s,e),n=await te.stat(t);if(n.isDirectory())return await this._createDirectorySession(e,t,n)}catch{}try{let t=N.join(s,`${e}.jsonl`),n=await te.stat(t);if(n.isFile())return await this._createFileSession(`${e}.jsonl`,t,n)}catch{}return null}async resolveEventsFile(e,s){let t=e.id,n=N.join(s,t);try{return(await te.stat(n)).isDirectory()?N.join(n,"events.jsonl"):N.join(s,`${t}.jsonl`)}catch{return N.join(s,`${t}.jsonl`)}}async readEvents(e,s){let t=await this.resolveEventsFile(e,s);return this.readJsonlEvents(t)}async _createDirectorySession(e,s,t){let n=N.join(s,"workspace.yaml"),r=N.join(s,"events.jsonl"),a=N.join(s,".imported"),o=N.join(s,`${e}.agent-review.md`),i=await se(n)?await fn(n):{summary:e,repo:"unknown"},l=await se(r)?await Ct(r):0,c=await se(a),u=await se(o),d=null,f=null,g=null,m="completed";if(await se(r)){let S=await vt(r);if(d=S.duration,f=S.copilotVersion,g=S.selectedModel,m=xt(S),!i.summary&&S.firstUserMessage&&(i.summary=S.firstUserMessage),S.lastEventTime){let T=new Date(S.lastEventTime).getTime(),b=new Date(t.mtime).getTime();T>b&&(t={...t,mtime:new Date(T)})}}let y=bt.fromDirectory(s,e,t,i,l,d,c,u,f,g,m);return y.source="copilot",y}async _createFileSession(e,s,t){let n=e.replace(".jsonl",""),r=await Ct(s),a=await vt(s),o=xt(a),i=bt.fromFile(s,n,t,r,a.firstUserMessage,a.duration,a.copilotVersion,a.selectedModel,o);return i.source="copilot",i}};jt.exports=Te});var W=w(($r,At)=>{var be=class{canParse(e){throw new Error("canParse() must be implemented")}parse(e){throw new Error("parse() must be implemented")}getMetadata(e){throw new Error("getMetadata() must be implemented")}extractTurns(e){throw new Error("extractTurns() must be implemented")}extractToolCalls(e){throw new Error("extractToolCalls() must be implemented")}};At.exports=be});var ve=w((Or,Dt)=>{var hn=W(),Ce=class extends hn{canParse(e){if(!e||e.length===0)return!1;let s=["session.start","user.message","assistant.turn_start","assistant.message","tool.execution_start"];return e.some(t=>t.type&&s.some(n=>t.type.startsWith(n)))}parse(e){return{metadata:this.getMetadata(e),turns:this.extractTurns(e),toolCalls:this.extractToolCalls(e),allEvents:e}}getMetadata(e){let s=e.find(n=>n.type==="session.start");if(!s)return null;let t=s.data||{};return{sessionId:t.sessionId,startTime:t.startTime,model:t.selectedModel,version:t.copilotVersion,producer:t.producer,cwd:t.context?.cwd,gitRoot:t.context?.gitRoot,branch:t.context?.branch,repository:t.context?.repository}}extractTurns(e){let s=[],t=null;for(let n of e)if(n.type==="user.message")t&&s.push(t),t={turnId:n.id,userMessage:{id:n.id,content:n.data?.content||"",transformedContent:n.data?.transformedContent,timestamp:n.timestamp},assistantMessages:[],toolCalls:[]};else if(n.type==="assistant.message"&&t)t.assistantMessages.push({id:n.id,messageId:n.data?.messageId,content:n.data?.content||"",toolRequests:n.data?.toolRequests||[],reasoningText:n.data?.reasoningText,timestamp:n.timestamp});else if(n.type.startsWith("tool.execution_")&&t){let r=n.data?.toolCallId,a=t.toolCalls.find(o=>o.toolCallId===r);a||(a={toolCallId:r,events:[]},t.toolCalls.push(a)),a.events.push(n),n.type==="tool.execution_start"?(a.name=n.data?.toolName,a.arguments=n.data?.arguments):n.type==="tool.execution_complete"&&(a.result=n.data?.result,a.exitCode=n.data?.exitCode)}return t&&s.push(t),s}extractToolCalls(e){let s=[],t=new Map;for(let n of e)if(n.type==="tool.execution_start"){let r=n.data?.toolCallId;t.set(r,{toolCallId:r,name:n.data?.toolName,arguments:n.data?.arguments,startEvent:n,completeEvent:null})}else if(n.type==="tool.execution_complete"){let r=n.data?.toolCallId,a=t.get(r);a&&(a.completeEvent=n,a.result=n.data?.result,a.exitCode=n.data?.exitCode,s.push(a))}return s}};Dt.exports=Ce});var je=w((Pr,kt)=>{var yn=W(),xe=class extends yn{canParse(e){return!e||e.length===0?!1:e.some(s=>s.type&&["user","assistant"].includes(s.type)&&s.uuid&&Object.prototype.hasOwnProperty.call(s,"parentUuid")&&s.sessionId)}parse(e){return{metadata:this.getMetadata(e),turns:this.extractTurns(e),toolCalls:this.extractToolCalls(e),allEvents:e}}getMetadata(e){let s=e.find(r=>r.type==="user");if(!s)return null;let n=e.find(r=>r.type==="assistant"&&r.message?.model)?.message?.model||"unknown";return{sessionId:s.sessionId,startTime:s.timestamp,model:n,version:s.version,producer:"claude-code",cwd:s.cwd,gitRoot:null,branch:s.gitBranch,repository:null}}extractTurns(e){let s=[],t=e.filter(a=>["user","assistant"].includes(a.type)&&a.type!=="file-history-snapshot"&&a.type!=="queue-operation"),n=new Map;for(let a of t)n.set(a.uuid,a);let r=t.filter(a=>a.type==="user"&&(!a.parentUuid||!n.has(a.parentUuid)));for(let a of r){let o={turnId:a.uuid,userMessage:{id:a.uuid,content:this._extractMessageContent(a.message),timestamp:a.timestamp},assistantMessages:[],toolCalls:[]};this._collectAssistantResponses(a.uuid,n,o),s.push(o)}return s}_collectAssistantResponses(e,s,t){for(let[n,r]of s.entries())if(r.parentUuid===e&&r.type==="assistant"){let a={id:r.uuid,messageId:r.message?.id,content:this._extractMessageContent(r.message),model:r.message?.model,timestamp:r.timestamp},o=this._extractToolUse(r.message);o.length>0&&(a.toolRequests=o,t.toolCalls.push(...o.map(i=>({toolCallId:i.id,name:i.name,arguments:i.input,parentUuid:r.uuid})))),t.assistantMessages.push(a),this._collectAssistantResponses(r.uuid,s,t)}}_extractMessageContent(e){return!e||!e.content?"":typeof e.content=="string"?e.content:Array.isArray(e.content)?e.content.filter(s=>s.type==="text").map(s=>s.text).join(`
|
|
3
|
+
`):""}_extractToolUse(e){return!e||!e.content||!Array.isArray(e.content)?[]:e.content.filter(s=>s.type==="tool_use").map(s=>({id:s.id,name:s.name,input:s.input}))}extractToolCalls(e){let s=[];for(let t of e)if(t.type==="assistant"&&t.message?.content){let n=this._extractToolUse(t.message);for(let r of n)s.push({toolCallId:r.id,name:r.name,arguments:r.input,parentUuid:t.uuid,timestamp:t.timestamp,result:null,exitCode:null})}return s}};kt.exports=xe});var De=w((Rr,Mt)=>{var Sn=W(),Ae=class extends Sn{constructor(){super("pi-mono")}async parseSessionDir(e){let s=require("fs").promises,t=require("path");try{let r=(await s.readdir(e)).filter(u=>u.endsWith(".jsonl"));if(r.length===0)return null;r.sort().reverse();let a=t.join(e,r[0]),o=await this._readFirstLine(a);if(!o)return null;let i=JSON.parse(o);if(i.type!=="session")return console.warn(`Pi-Mono file ${a} doesn't start with session event`),null;let c=t.basename(e).replace(/^--/,"").replace(/--$/,"");return{id:i.id,type:"pi-mono",source:"pi-mono",cwd:i.cwd||c,createdAt:new Date(i.timestamp),updatedAt:new Date(i.timestamp),summary:`Pi-Mono: ${c}`,fileCount:r.length}}catch(n){return console.error(`Error parsing Pi-Mono session dir ${e}:`,n.message),null}}async _readFirstLine(e){let s=require("fs"),t=require("readline");return new Promise(n=>{let r=s.createReadStream(e,{encoding:"utf-8"}),a=t.createInterface({input:r,crlfDelay:1/0});a.on("line",o=>{a.close(),r.destroy(),n(o.trim())}),a.on("close",()=>n(null))})}async parseEvents(e){let s=require("fs"),t=require("readline"),n=[],r=s.createReadStream(e,{encoding:"utf-8"}),a=t.createInterface({input:r,crlfDelay:1/0}),o=0;for await(let i of a){o++;let l=i.trim();if(l)try{let c=JSON.parse(l);n.push(c)}catch(c){console.error(`Error parsing Pi-Mono line ${o}:`,c.message)}}return n}};Mt.exports=Ae});var $t=w((qr,Nt)=>{var wn=W(),ke=class extends wn{canParse(e){if(!Array.isArray(e)||e.length===0)return!1;let s=e[0];return!!(s&&typeof s=="object"&&s.kind===0&&s.v&&s.v.sessionId)}parseVsCode(e){let s=this._getMetadata(e),t=this._toEvents(e);return{metadata:s,turns:this._extractTurns(t),toolCalls:this._extractToolCalls(t),allEvents:t}}parseJsonl(e){let s=this.replayMutations(e),t=this._getMetadata(s),n=this._toEvents(s);return{metadata:t,turns:this._extractTurns(n),toolCalls:this._extractToolCalls(n),allEvents:n}}replayMutations(e){let s=null;for(let t of e){if(!t||typeof t!="object")continue;let{kind:n,k:r,v:a,i:o}=t;switch(n){case 0:s=a;break;case 1:r&&Array.isArray(r)&&this._applySet(s,r,a);break;case 2:r&&Array.isArray(r)&&this._applyPush(s,r,a,o);break;case 3:r&&Array.isArray(r)&&this._applyDelete(s,r);break;default:console.warn(`[VsCodeParser] Unknown mutation kind: ${n}`)}}return s}_applySet(e,s,t){if(!e||s.length===0)return;let n=e;for(let a=0;a<s.length-1;a++){let o=s[a];n[o]||(n[o]=typeof s[a+1]=="number"?[]:{}),n=n[o]}let r=s[s.length-1];n[r]=t}_applyPush(e,s,t,n){if(!e||s.length===0)return;let r=e;for(let i=0;i<s.length-1;i++){let l=s[i];r[l]||(r[l]=typeof s[i+1]=="number"?[]:{}),r=r[l]}let a=s[s.length-1];r[a]||(r[a]=[]);let o=r[a];if(!Array.isArray(o)){console.warn(`[VsCodeParser] Push target is not an array: ${s.join(".")}`);return}n!=null&&(o.length=n),t&&Array.isArray(t)&&t.length>0&&o.push(...t)}_applyDelete(e,s){if(!e||s.length===0)return;let t=e;for(let r=0;r<s.length-1;r++){let a=s[r];if(!t[a])return;t=t[a]}let n=s[s.length-1];delete t[n]}parse(e){return Array.isArray(e)&&e.length>0&&this.canParse(e)?this.parseJsonl(e):null}getMetadata(e){let s=this.parse(e);return s?s.metadata:null}extractTurns(e){let s=this.parse(e);return s?s.turns:[]}extractToolCalls(e){let s=this.parse(e);return s?s.toolCalls:[]}_getMetadata(e){let s=e.requests||[],t=s[0]||{},n=s[s.length-1]||{},r=t.agent?.name||t.agent?.id||"vscode-copilot";return{sessionId:e.sessionId,startTime:e.creationDate?new Date(e.creationDate).toISOString():t.timestamp?new Date(t.timestamp).toISOString():null,endTime:e.lastMessageDate?new Date(e.lastMessageDate).toISOString():n.timestamp?new Date(n.timestamp).toISOString():null,model:t.modelId||null,producer:"vscode-copilot-chat",version:t.agent?.extensionVersion||null,agentName:r,requestCount:s.length}}_toEvents(e){let s=[],t=e.requests||[];s.push({type:"session.start",id:`${e.sessionId}-start`,timestamp:e.creationDate?new Date(e.creationDate).toISOString():null,data:{sessionId:e.sessionId,producer:"vscode-copilot-chat",selectedModel:t[0]?.modelId||null}});for(let n of t){let r=n.timestamp?new Date(n.timestamp).toISOString():null,a=n.modelState?.completedAt?new Date(n.modelState.completedAt).toISOString():r,o=Array.isArray(n.response)?n.response:[],i=this._buildSubAgentNameMap(o),l=this._extractUserText(n.message);s.push({type:"user.message",id:n.requestId,timestamp:r,data:{message:l,content:l}}),s.push({type:"assistant.turn_start",id:`${n.requestId}-turn`,timestamp:r,parentId:n.requestId,data:{}});let c="",u=0,d=null,f=()=>{let g=c.trim().replace(/^`{3,}$/gm,"").trim();if(c="",!g)return;let m=d,y=m?i[m]||m.slice(0,8):null;s.push({type:"assistant.message",id:`${n.requestId}-text-${u}`,timestamp:a,parentId:n.requestId,data:{message:g,content:g,tools:[],subAgentId:m||null,subAgentName:y,parentToolCallId:null}})};for(let g of o)switch(u++,g.kind){case"thinking":{let m=g.content?.value||g.content||"";m&&(c+=m+`
|
|
4
|
+
`);break}case"markdownContent":{let m=g.content?.value||g.content||"";m&&(c+=m+`
|
|
5
|
+
`);break}case void 0:case null:{let m=g.value||"";m&&(c+=m);break}case"inlineReference":{let m=g.name||"";m&&(c+="`"+m+"`");break}case"toolInvocationSerialized":{f();let m=g.toolId==="runSubagent"?g.toolCallId:g.subAgentInvocationId;g.toolId==="runSubagent"&&(d=m),m&&(d=m);let y=this._normalizeTool(g);if(y){let S=m?i[m]||m.slice(0,8):null;s.push({type:"tool.invocation",id:y.id||`${n.requestId}-tool-${u}`,timestamp:a,parentId:n.requestId,data:{tool:y,subAgentId:m||null,subAgentName:S,parentToolCallId:m||null,badgeLabel:y.name,badgeClass:y.status==="error"?"badge-error":"badge-tool"}})}break}case"textEditGroup":{f();let m=g.edits||g.uri?[g]:[];s.push({type:"tool.invocation",id:`${n.requestId}-edit-${u}`,timestamp:a,parentId:n.requestId,data:{tool:{type:"tool_use",id:`${n.requestId}-edit-${u}`,name:"textEdit",startTime:r,endTime:r,status:"completed",input:{uri:g.uri,edits:m},result:"file edit",error:null},badgeLabel:"textEdit",badgeClass:"badge-tool"}});break}case"prepareToolInvocation":case"undoStop":case"codeblockUri":case"mcpServersStarting":break;default:break}f()}return s}_buildSubAgentNameMap(e){let s={};for(let t of e){if(!t||typeof t!="object"||t.kind!=="toolInvocationSerialized"||t.toolId!=="runSubagent")continue;let n=t.toolCallId;if(!n||s[n])continue;let r=t.toolSpecificData?.agentName;if(r){s[n]=r;continue}let a=t.invocationMessage,o=typeof a=="string"?a:a&&typeof a=="object"&&a.value||"";if(o){s[n]=o;continue}let i=o.match(/agents\/([^/\]]+?)\.agent\.md/);if(i){s[n]=i[1];continue}let l=t.resultDetails,c=Array.isArray(l)?l:l?[l]:[];for(let u of c){if(typeof u!="object")continue;if(i=(u.fsPath||u.path||"").match(/agents\/([^/]+?)\.agent\.md/),i){s[n]=i[1];break}}}return s}_extractUserText(e){return e?typeof e.text=="string"?e.text:Array.isArray(e.parts)?e.parts.filter(s=>s.kind==="text").map(s=>s.text||"").join(""):"":""}_normalizeTool(e){if(!e.toolCallId)return null;let s=e.toolSpecificData||{},t=s.input||s.parameters||s.request||{},n=s.output||s.result||null,r=e.isConfirmed===!1;if(!n&&(e.generatedTitle||e.resultDetails))if(e.resultDetails){let l=(Array.isArray(e.resultDetails)?e.resultDetails:[e.resultDetails]).map(c=>c.fsPath||c.path||c.external||JSON.stringify(c)).filter(Boolean);n=l.length>0?l.join(`
|
|
6
|
+
`):e.generatedTitle||null}else n=e.generatedTitle||null;if(Object.keys(t).length===0&&e.invocationMessage){let i=e.invocationMessage,l=typeof i=="string"?i:i&&typeof i=="object"&&i.value||"";l&&(t={description:l})}let a=i=>{if(!i||typeof i!="object")return i;let l=i.fsPath||i.path||i.external||"";return l?l.replace(/.*\//,""):JSON.stringify(i)},o=i=>{if(!i||typeof i!="object")return i;let l={};for(let[c,u]of Object.entries(i))if(!(c==="$mid"||c==="external"||c==="scheme")){if(c==="fsPath"||c==="path"){l.file=u.replace(/.*\//,"");continue}u&&typeof u=="object"&&("fsPath"in u||"$mid"in u)?l[c]=a(u):Array.isArray(u)&&c==="edits"?l.edits=`${u.length} edit(s)`:l[c]=u}return l};return t&&typeof t=="object"&&!t.description&&(t=o(t)),{type:"tool_use",id:e.toolCallId,name:e.toolId||"unknown",startTime:null,endTime:null,status:r?"error":e.isComplete?"completed":"pending",input:t,result:typeof n=="string"?n:JSON.stringify(n),error:r?e.resultDetails||"Tool invocation not confirmed":null}}_extractTurns(e){let s=[],t=null;for(let n of e)n.type==="user.message"?(t&&s.push(t),t={userMessage:n,assistantMessages:[],toolCalls:[]}):t&&(n.type==="assistant.message"?t.assistantMessages.push(n):n.type==="tool.invocation"&&t.toolCalls.push(n.data?.tool));return t&&s.push(t),s}_extractToolCalls(e){return e.filter(s=>s.type==="tool.invocation"&&s.data?.tool).map(s=>s.data.tool)}};Nt.exports=ke});var Pt=w((Fr,Ot)=>{var Me=ve(),Ne=je(),$e=De(),Oe=class{constructor(){this.parsers=[new Me,new Ne,new $e],this.parserMap={copilot:new Me,claude:new Ne,"pi-mono":new $e}}getParser(e){if(typeof e=="string")return this.parserMap[e]||null;let s=e;for(let t of this.parsers)if(t.canParse(s))return t;return null}parse(e){let s=this.getParser(e);return s?s.parse(e):null}getParserType(e){let s=this.getParser(e);return s?s instanceof Me?"copilot":s instanceof Ne?"claude":s instanceof $e?"pi-mono":"unknown":null}};Ot.exports=Oe});var Pe=w((Ur,Rt)=>{var _n=W(),In=ve(),Tn=je(),En=De(),bn=$t(),Cn=Pt();Rt.exports={BaseSessionParser:_n,CopilotSessionParser:In,ClaudeSessionParser:Tn,PiMonoParser:En,VsCodeParser:bn,ParserFactory:Cn}});var zt=w((Lr,Lt)=>{var k=require("path"),vn=require("os"),A=require("fs").promises,xn=B(),qt=ee(),{countLines:Ft,shouldSkipEntry:Ut}=V(),{ParserFactory:jn}=Pe(),Re=class extends xn{constructor(){super(),this.parserFactory=new jn}get type(){return"claude"}get displayName(){return"Claude"}get envVar(){return"CLAUDE_SESSION_DIR"}getDefaultDir(){return k.join(vn.homedir(),".claude","projects")}async scanEntries(e){let t=(await A.readdir(e)).filter(r=>!Ut(r)).map(async r=>{let a=k.join(e,r);return(await A.stat(a)).isDirectory()?this._scanProjectDir(a,r):null});return(await Promise.allSettled(t)).filter(r=>r.status==="fulfilled"&&r.value!==null&&r.value!==void 0).map(r=>r.value).flat()}async findById(e,s){try{let t=await A.readdir(s);for(let n of t){let r=k.join(s,n),a=k.join(r,`${e}.jsonl`);try{let i=await A.stat(a);if(i.isFile()){let l=await this._createClaudeSession(`${e}.jsonl`,a,i,n);if(l)return l}}catch{}let o=k.join(r,e);try{let i=await A.stat(o);if(i.isDirectory()){let l=k.join(o,"subagents");try{if((await A.stat(l)).isDirectory())return await this._createSubagentsSession(e,o,i,n)}catch{}}}catch{}}}catch{}return null}async resolveEventsFile(e,s){if(e.type==="directory")return null;try{let t=await A.readdir(s);for(let n of t){let r=k.join(s,n,`${e.id}.jsonl`);try{return await A.access(r),r}catch{}}}catch(t){console.error("Error searching Claude projects:",t)}return null}async readEvents(e,s){let t=await this.resolveEventsFile(e,s);return this.readJsonlEvents(t)}async _scanProjectDir(e,s){try{let t=await A.readdir(e),n=[];for(let r of t){if(Ut(r))continue;let a=k.join(e,r),o=await A.stat(a);if(o.isFile()&&r.endsWith(".jsonl")){let i=await this._createClaudeSession(r,a,o,s);i&&n.push(i)}if(o.isDirectory()){let i=k.join(a,"subagents");try{if((await A.stat(i)).isDirectory()){let c=await this._createSubagentsSession(r,a,o,s);c&&n.push(c)}}catch{}}}return n}catch(t){return console.error(`Error scanning Claude project dir ${e}:`,t.message),[]}}async _createClaudeSession(e,s,t,n){let r=e.replace(".jsonl",""),a=await Ft(s);try{let l=(await A.readFile(s,"utf-8")).trim().split(`
|
|
7
|
+
`).filter(y=>y.trim()).map(y=>{try{return JSON.parse(y)}catch{return null}}).filter(y=>y!==null),c=l.some(y=>y.type==="assistant"||y.type==="user"),u=l.some(y=>y.type==="assistant.message"||y.type==="user.message");if(!c&&u||!c||this.parserFactory.getParserType(l)!=="claude")return null;let f=this.parserFactory.parse(l),g=f.metadata||{},m=n.replace(/^-/,"/").replace(/-/g,"/");return new qt(r,"file",{source:"claude",filePath:s,directory:k.dirname(s),workspace:{summary:g.model?`Claude Code session (${g.model})`:"Claude Code session",cwd:g.cwd||m},createdAt:g.startTime||t.birthtime,updatedAt:t.mtime,summary:f.turns[0]?.userMessage?.content?.substring(0,100)||"No summary",hasEvents:a>0,eventCount:a,duration:null,isImported:!1,hasInsight:!1,copilotVersion:g.version,selectedModel:g.model,sessionStatus:"completed"})}catch(o){return console.error(`Error creating Claude session ${r}:`,o.message),null}}async _createSubagentsSession(e,s,t,n){try{let r=k.join(s,"subagents"),o=(await A.readdir(r)).filter(m=>m.startsWith("agent-")&&m.endsWith(".jsonl"));if(o.length===0)return null;let i=0;for(let m of o){let y=k.join(r,m);i+=await Ft(y)}let l=k.join(r,o[0]),u=(await A.readFile(l,"utf-8")).trim().split(`
|
|
8
|
+
`).filter(m=>m.trim()),d=u.length>0?JSON.parse(u[0]):null,f={cwd:d?.cwd||n,version:d?.version,model:d?.message?.model,startTime:d?.timestamp},g=n.replace(/^-/,"/").replace(/-/g,"/");return new qt(e,"directory",{source:"claude",directory:s,workspace:{summary:`Claude session (${o.length} sub-agents)`,cwd:f.cwd||g},createdAt:f.startTime||t.birthtime,updatedAt:t.mtime,summary:d?.message?.content?.substring(0,100)||"Sub-agent tasks",hasEvents:i>0,eventCount:i,duration:null,isImported:!1,hasInsight:!1,copilotVersion:f.version,selectedModel:f.model,sessionStatus:"completed"})}catch(r){return console.error(`Error creating Claude subagents session ${e}:`,r.message),null}}};Lt.exports=Re});var Jt=w((zr,Ht)=>{var $=require("path"),An=require("os"),P=require("fs").promises,Dn=B(),Vt=ee(),{countLines:Bt,shouldSkipEntry:kn}=V(),{readFirstLine:Wt}=Ie(),qe=class extends Dn{get type(){return"pi-mono"}get displayName(){return"Pi"}get envVar(){return"PI_MONO_SESSION_DIR"}getDefaultDir(){return $.join(An.homedir(),".pi","agent","sessions")}async scanEntries(e){let t=(await P.readdir(e)).filter(r=>!kn(r)).map(async r=>{let a=$.join(e,r);return(await P.stat(a)).isDirectory()?this._scanProjectDir(a,r):null});return(await Promise.allSettled(t)).filter(r=>r.status==="fulfilled"&&r.value!==null&&r.value!==void 0).map(r=>r.value).flat()}async findById(e,s){try{let t=await P.readdir(s);for(let n of t){let r=$.join(s,n);try{let o=(await P.readdir(r)).find(i=>i.includes(`_${e}.jsonl`));if(o){let i=$.join(r,o),l=await P.stat(i);return await this._createSession(o,i,l,n)}}catch{}}}catch(t){console.error("Error searching Pi-Mono sessions:",t)}return null}async _createSession(e,s,t,n){let r=e.match(/_([a-f0-9-]+)\.jsonl$/);if(!r)return null;let a=r[1],o=await Wt(s);if(!o)return null;try{let i=JSON.parse(o);if(i.type!=="session")return null;let l=await Bt(s),c=n.replace(/^--/,"").replace(/--$/,"");return new Vt(a,"directory",{source:"pi-mono",directory:$.dirname(s),workspace:{cwd:i.cwd||c},createdAt:new Date(i.timestamp),updatedAt:new Date(t.mtime),summary:`Pi-Mono: ${$.basename(i.cwd||c)}`,hasEvents:l>0,eventCount:l,duration:null,sessionStatus:"completed"})}catch(i){return console.error(`[PI-MONO] Error parsing session ${e}:`,i.message),null}}async resolveEventsFile(e,s){try{let t=await P.readdir(s);for(let n of t){let r=$.join(s,n);try{let o=(await P.readdir(r)).find(i=>i.includes(`_${e.id}.jsonl`));if(o)return $.join(r,o)}catch{}}}catch(t){console.error("Error searching Pi-Mono sessions:",t)}return null}async readEvents(e,s){let t=await this.resolveEventsFile(e,s);return this.readJsonlEvents(t)}async _scanProjectDir(e,s){try{let n=(await P.readdir(e)).filter(a=>a.endsWith(".jsonl"));if(n.length===0)return[];let r=[];n.sort().reverse();for(let a of n){let o=$.join(e,a),i=await P.stat(o),l=a.match(/_([a-f0-9-]+)\.jsonl$/);if(!l)continue;let c=l[1],u=await Wt(o);if(u)try{let d=JSON.parse(u);if(d.type!=="session")continue;let f=await Bt(o),g=s.replace(/^--/,"").replace(/--$/,""),m=new Vt(c,"directory",{source:"pi-mono",directory:e,workspace:{cwd:d.cwd||g},createdAt:new Date(d.timestamp),updatedAt:new Date(i.mtime),summary:`Pi-Mono: ${$.basename(d.cwd||g)}`,hasEvents:f>0,eventCount:f,duration:null,sessionStatus:"completed"});r.push(m)}catch(d){console.error(`[PI-MONO] Error parsing session ${a}:`,d.message)}}return r}catch(t){return console.error(`[PI-MONO] Error scanning dir ${e}:`,t.message),[]}}};Ht.exports=qe});var Zt=w((Vr,Yt)=>{var C=require("path"),ne=require("os"),M=require("fs").promises,{fileURLToPath:Gt}=require("url"),Mn=B(),Nn=ee(),{shouldSkipEntry:Kt}=V(),{VsCodeParser:$n}=Pe();function On(){let p;switch(ne.platform()){case"win32":p=C.join(process.env.APPDATA||C.join(ne.homedir(),"AppData","Roaming"));break;case"darwin":p=C.join(ne.homedir(),"Library","Application Support");break;case"linux":p=C.join(ne.homedir(),".config");break;default:p=C.join(ne.homedir(),".config")}return[C.join(p,"Code","User","workspaceStorage"),C.join(p,"Code - Insiders","User","workspaceStorage")]}var Fe=class extends Mn{constructor(){super(),this._candidates=null,this._parser=new $n}get type(){return"vscode"}get displayName(){return"Copilot Chat"}get envVar(){return"VSCODE_WORKSPACE_STORAGE_DIR"}get hasCustomPipeline(){return!0}getDefaultDir(){return this._getCandidates()[0]}_getCandidates(){return this._candidates||(this._candidates=On()),this._candidates}async resolveDir(){if(this.envVar&&process.env[this.envVar])return process.env[this.envVar];let e=this._getCandidates();for(let s of e)try{return await M.access(s),s}catch{}return null}async scanEntries(e){let t=(await M.readdir(e)).filter(r=>!Kt(r)).map(async r=>{let a=C.join(e,r);return(await M.stat(a)).isDirectory()?this._scanWorkspaceDir(a):null});return(await Promise.allSettled(t)).filter(r=>r.status==="fulfilled"&&r.value!==null&&r.value!==void 0).map(r=>r.value).flat()}async findById(e,s){try{let t=await M.readdir(s),n=[];for(let r of t){let a=C.join(s,r,"chatSessions");try{let i=(await M.readdir(a)).find(l=>l===`${e}.json`||l===`${e}.jsonl`||l.replace(/\.jsonl?$/,"")===e);if(i){let l=C.join(a,i),c=await M.stat(l),u=await this._parseSessionFile(l);if(!u)continue;let{sessionJson:d}=u,f=d.requests||[];if(f.length===0)continue;let g=await this._resolveWorkspacePath(C.join(s,r)),m={...c,filePath:l};n.push(this._buildSession(e,f,d,m,r,g||C.join(s,r)))}}catch{}}if(n.length>0)return n.sort((r,a)=>(a.updatedAt?.getTime?.()??0)-(r.updatedAt?.getTime?.()??0)),n[0]}catch(t){console.error(`[VSCode findById] Error searching VSCode sessions: ${t.message}`)}return null}async readEvents(e,s){if(!e?.filePath)return[];try{let t=await this._parseSessionFile(e.filePath);if(!t)return[];let n=this._expandVsCodeEvents(t.parsed.allEvents);return n=await this._applyFileMtimeFallback(n,e.filePath),this._expandVsCodeToTimelineFormat(n)}catch(t){return console.error(`[VSCode readEvents] Error reading session ${e.id}:`,t),[]}}buildTimeline(e,s){let t=[],n=0,r=new Set;for(let o=0;o<e.length;o++){let i=e[o];if(i.type!=="user.message")continue;n++;let l={id:`turn-${n}`,type:"user-request",message:i.data?.message||"",startTime:i.timestamp,endTime:i.timestamp,assistantTurns:[],subagents:[]},c=new Set,u=0,d=o+1;for(;d<e.length&&e[d].type!=="user.message";){let f=e[d];if(f.type==="assistant.message"){u++,l.endTime=f.timestamp||l.endTime;let g={id:`assistant-${u}`,startTime:f.timestamp,endTime:f.timestamp,tools:[]};if(Array.isArray(f.data?.tools))for(let y of f.data.tools)g.tools.push({name:y.name,startTime:y.startTime||f.timestamp,endTime:y.endTime||f.timestamp,status:y.status||"completed",input:y.input,result:y.result});let m=f.data?.subAgentId;m&&!c.has(m)&&(c.add(m),r.add(m),l.subagents.push({id:m,name:f.data?.subAgentName||m,startTime:f.timestamp,endTime:f.timestamp})),l.assistantTurns.push(g)}d++}t.push(l)}let a=t.reduce((o,i)=>o+i.assistantTurns.reduce((l,c)=>l+c.tools.length,0),0);return{turns:t,summary:{totalTurns:t.length,totalAssistantTurns:t.reduce((o,i)=>o+i.assistantTurns.length,0),totalTools:a,totalSubagents:r.size,startTime:e[0]?.timestamp,endTime:e[e.length-1]?.timestamp}}}async _scanWorkspaceDir(e){let s=C.join(e,"chatSessions");try{await M.access(s)}catch{return[]}let t=C.basename(e),n=await this._resolveWorkspacePath(e),a=(await M.readdir(s)).filter(i=>(i.endsWith(".json")||i.endsWith(".jsonl"))&&!Kt(i));if(a.length===0)return[];let o=[];for(let i of a){let l=C.join(s,i);try{let c=await M.stat(l),u=await this._parseSessionFile(l);if(!u)continue;let{sessionJson:d}=u,f=d.sessionId||C.basename(i).replace(/\.jsonl?$/,""),g=d.requests||[];if(g.length===0)continue;let m={...c,filePath:l},y=this._buildSession(f,g,d,m,t,n||e);o.push(y)}catch(c){console.warn(`[VSCode scan] Skipping malformed session file ${l}: ${c.message}`)}}return o}async _parseSessionFile(e){let s=await M.readFile(e,"utf-8");return this._parseSessionContent(s,e)}_parseSessionContent(e,s="unknown"){let t=e.trim();if(!t)return null;try{let a=JSON.parse(t);if(a&&typeof a=="object"&&!Array.isArray(a))return{sessionJson:a,parsed:this._parser.parseVsCode(a)}}catch{}let n=t.split(`
|
|
9
|
+
`).filter(a=>a.trim()),r=[];for(let a=0;a<n.length;a++)try{r.push(JSON.parse(n[a]))}catch(o){return console.warn(`[VSCode parse] Failed to parse ${s} line ${a+1}: ${o.message}`),null}return r.length===0?null:this._parser.canParse(r)?{sessionJson:this._parser.replayMutations(r),parsed:this._parser.parseJsonl(r)}:r.length===1&&r[0]&&typeof r[0]=="object"?{sessionJson:r[0],parsed:this._parser.parseVsCode(r[0])}:(console.warn(`[VSCode parse] Unsupported session format in ${s}`),null)}_parseJsonl(e,s="unknown"){return this._parseSessionContent(e,s)?.sessionJson||null}async _applyFileMtimeFallback(e,s){if(!e.length)return e;try{let t=await M.stat(s),n=new Date(t.mtime).toISOString(),r=e[e.length-1];if(!r?.timestamp)return e;let a=new Date(r.timestamp).getTime();(new Date(n).getTime()-a)/1e3>10&&(r.timestamp=n)}catch(t){console.error("[VSCode] Error getting file mtime:",t)}return e}async _resolveWorkspacePath(e){try{let s=C.join(e,"workspace.json"),t=await M.readFile(s,"utf-8"),n=JSON.parse(t);if(n.folder)return Gt(n.folder);if(n.workspace){let r=Gt(n.workspace);try{let a=await M.readFile(r,"utf-8"),o=JSON.parse(a);if(Array.isArray(o.folders)&&o.folders.length>0){let i=C.dirname(r);return C.resolve(i,o.folders[0].path)}}catch{}}}catch{}return null}_buildSession(e,s,t,n,r,a){let o=s[0],i=s[s.length-1],l=t.creationDate?new Date(t.creationDate):o.timestamp?new Date(o.timestamp):n.birthtime,c=i.timestamp?new Date(i.timestamp):null,u=t.lastMessageDate?new Date(t.lastMessageDate):c||n.mtime,f=this._extractLastTerminalTimestamp(s)||c||u,g=Date.now()-f.getTime()<900*1e3,m=this._extractUserText(o.message);return new Nn(e,"file",{source:"vscode",filePath:n.filePath,directory:C.dirname(n.filePath),createdAt:l,updatedAt:f,summary:m?m.slice(0,120):`VSCode chat (${s.length} requests)`,hasEvents:!0,eventCount:s.reduce((y,S)=>y+(S.response||[]).length,0)+s.length*2+1,duration:f.getTime()-l.getTime(),sessionStatus:g?"wip":"completed",selectedModel:o.modelId||null,copilotVersion:o.agent?.extensionVersion||null,workspace:{cwd:a,workspaceHash:r}})}_expandVsCodeEvents(e){let s=[],t=[],n=null,r=null,a=0,o=null,i=null,l=()=>{t.length!==0&&(s.push({type:"assistant.message",id:`vscode-tools-${a}`,timestamp:r,parentId:n,data:{message:"",content:"",tools:t,subAgentId:o,subAgentName:i},_synthetic:!0}),t=[],o=null,i=null)};for(let c=0;c<e.length;c++){let u=e[c];if(u.type==="tool.invocation"){let d=u.data?.subAgentId||null;t.length>0&&d!==o&&l(),t.length===0&&(n=u.parentId,r=u.timestamp,a=c,o=d,i=u.data?.subAgentName||null),u.data?.tool&&t.push(u.data.tool);continue}l(),s.push(u)}return l(),s}_expandVsCodeToTimelineFormat(e){let s=[];for(let t=0;t<e.length;t++){let n=e[t];s.push(n),!(n.type!=="assistant.message"||!Array.isArray(n.data?.tools)||n.data.tools.length===0)&&n.data.tools.forEach((r,a)=>{if(!r.id||!r.name)return;let o=r.startTime||n.timestamp,i=r.endTime||n.timestamp;s.push({type:"tool.execution_start",id:`${r.id}-start`,timestamp:o,parentId:n.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,arguments:r.input||{}},_synthetic:!0,_fileIndex:n._fileIndex?n._fileIndex+.1+a*.02:void 0}),s.push({type:"tool.execution_complete",id:`${r.id}-complete`,timestamp:i,parentId:r.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,result:r.result||null,error:r.error||(r.status==="error"?"Tool execution failed":null),isError:r.status==="error"},_synthetic:!0,_fileIndex:n._fileIndex?n._fileIndex+.15+a*.02:void 0})})}return s}_extractLastTerminalTimestamp(e){let s=0;function t(n){if(!(!n||typeof n!="object")){if(Array.isArray(n)){n.forEach(t);return}if(n.terminalCommandState&&typeof n.terminalCommandState.timestamp=="number"){let r=n.terminalCommandState.timestamp;r>1e12&&r<9999999999999&&r>s&&(s=r)}for(let r of Object.values(n))t(r)}}for(let n of e)t(n.response);return s>0?new Date(s):null}_extractUserText(e){return e?typeof e.text=="string"?e.text:Array.isArray(e.parts)?e.parts.filter(s=>s.kind==="text").map(s=>s.text||"").join(""):"":""}};Yt.exports=Fe});var Qt=w((Br,Xt)=>{var ue=require("path"),Pn=require("os"),Ue=require("fs").promises,Rn=Ee(),Le=class extends Rn{get type(){return"modernize"}get displayName(){return"Modernize CLI"}get envVar(){return"MODERNIZE_SESSION_DIR"}getDefaultDir(){return ue.join(Pn.homedir(),".modernize","configuration")}async resolveDir(){return this.envVar&&process.env[this.envVar]?process.env[this.envVar]:this.getDefaultDir()}async _findSessionStateDirs(e){let s=[];try{let t=await Ue.readdir(e);for(let n of t){if(!n.includes("+"))continue;let r=ue.join(e,n,"session-state");try{(await Ue.stat(r)).isDirectory()&&s.push(r)}catch{}}}catch{}return s}_isEnvVarOverride(){return!!(this.envVar&&process.env[this.envVar])}async scanEntries(e){if(this._isEnvVarOverride())return this._scanAndTag(e);let s=await this._findSessionStateDirs(e),t=[];for(let n of s){let r=await this._scanAndTag(n);t.push(...r)}return t}_extractModernizeVersion(e){let s=ue.basename(ue.dirname(e)),t=s.indexOf("+");return t>0?s.substring(0,t):null}async _scanAndTag(e){try{let s=this._extractModernizeVersion(e),t=await super.scanEntries(e);for(let n of t)n.source="modernize",n.modernizeVersion=s;return t}catch{return[]}}async findById(e,s){if(this._isEnvVarOverride())return this._findByIdInDir(e,s);let t=await this._findSessionStateDirs(s);for(let n of t){let r=await this._findByIdInDir(e,n);if(r)return r}return null}async _findByIdInDir(e,s){let t=await super.findById(e,s);return t&&(t.source="modernize",t.modernizeVersion=this._extractModernizeVersion(s)),t}async resolveEventsFile(e,s){if(this._isEnvVarOverride())return super.resolveEventsFile(e,s);let t=await this._findSessionStateDirs(s);for(let n of t)try{let r=await super.resolveEventsFile(e,n);return await Ue.access(r),r}catch{}return null}async readEvents(e,s){let t=await this.resolveEventsFile(e,s);return this.readJsonlEvents(t)}async _createDirectorySession(e,s,t){let n=await super._createDirectorySession(e,s,t);return n&&(n.source="modernize"),n}async _createFileSession(e,s,t){let n=await super._createFileSession(e,s,t);return n&&(n.source="modernize"),n}};Xt.exports=Le});var ce=w((Wr,ts)=>{var es=wt(),qn=B(),Fn=Ee(),Un=zt(),Ln=Jt(),zn=Zt(),Vn=Qt(),H=new es;H.register(new Fn);H.register(new Un);H.register(new Ln);H.register(new zn);H.register(new Vn);ts.exports={registry:H,AdapterRegistry:es,BaseSourceAdapter:qn}});var Ve=w((Hr,ns)=>{var ss=require("fs").promises,{shouldSkipEntry:Bn}=V(),{registry:Wn}=ce(),ze=class{constructor(e){if(this.registry=Wn,typeof e=="string")this.sources=[{type:"copilot",dir:e}];else if(Array.isArray(e))this.sources=e;else{this.sources=this.registry.all().map(s=>({type:s.type,dir:s.getDefaultDir()}));for(let s of this.sources){let t=this.registry.get(s.type);t&&t.envVar&&process.env[t.envVar]&&(s.dir=process.env[t.envVar]),s.type==="copilot"&&process.env.SESSION_DIR&&!process.env.COPILOT_SESSION_DIR&&(s.dir=process.env.SESSION_DIR)}}this._cache=new Map,this._cacheTTL=60*1e3,this._pendingScans=new Map}invalidateCache(e=null){e?(this._cache.delete(e),this._cache.delete(null)):this._cache.clear()}async findAll(e=null){let s=e||"__all__",t=this._cache.get(s);if(t&&Date.now()-t.timestamp<this._cacheTTL)return t.data;if(this._pendingScans.has(s))return this._pendingScans.get(s);let n=this._doFindAll(e).then(r=>(this._cache.set(s,{data:r,timestamp:Date.now()}),this._pendingScans.delete(s),r)).catch(r=>{throw this._pendingScans.delete(s),r});return this._pendingScans.set(s,n),n}async _doFindAll(e=null){let s=[],t=e?this.sources.filter(n=>n.type===e):this.sources;for(let n of t)try{let r=await this._scanSource(n);s.push(...r)}catch(r){console.error(`Error reading ${n.type} sessions from ${n.dir}:`,r.message)}return this._sortByUpdatedAt(this._deduplicateSessions(s))}async _scanSource(e){let s=this.registry.get(e.type);if(!s)return console.warn(`No adapter registered for source type: ${e.type}`),[];let t;if(e.dir?t=e.dir:t=await s.resolveDir(),!t)return console.warn(`No directory resolved for ${e.type}`),[];try{await ss.access(t)}catch{return console.warn(`Source directory not found: ${t}`),[]}return s.scanEntries(t)}_deduplicateSessions(e){let s=new Map;for(let t of e){let n=s.get(t.id);(!n||t.updatedAt&&n.updatedAt&&new Date(t.updatedAt)>new Date(n.updatedAt))&&s.set(t.id,t)}return Array.from(s.values())}async findById(e){if(Bn(e))return null;for(let s of this.sources){let t=this.registry.get(s.type);if(!t)continue;let n;if(s.dir?n=s.dir:n=await t.resolveDir(),!n)continue;try{await ss.access(n)}catch{console.warn(`Source directory not found: ${n}`);continue}let r=await t.findById(e,n);if(r)return r}return null}_sortByUpdatedAt(e){return e.sort((s,t)=>new Date(t.createdAt)-new Date(s.createdAt))}};ns.exports=ze});var as=w((Jr,rs)=>{var Be=class{normalizeEvents(e,s){return Array.isArray(e)?e.filter(t=>!t._isToolResultWrapper).map(t=>this.normalizeEvent(t,s)):(console.warn("[EventNormalizer] normalizeEvents: events is not an array",typeof e),[])}normalizeEvent(e,s){return!e||typeof e!="object"?(console.warn("[EventNormalizer] normalizeEvent: invalid event",e),e):this._isAssistantMessage(e)?this._normalizeAssistantMessage(e,s):this._isTimelineEvent(e)?this._normalizeTimelineEvent(e,s):e}_isAssistantMessage(e){return e.data?.tools&&Array.isArray(e.data.tools)&&e.data.tools.length>0?!0:e.type==="assistant.message"||e.type==="assistant"||e.type==="user.message"||e.type==="user"}_isTimelineEvent(e){return e.type?.startsWith("tool.")||e.type?.startsWith("subagent.")}_normalizeAssistantMessage(e,s){let t={...e};return e.data?.tools&&Array.isArray(e.data.tools)&&(t.data={...e.data,tools:e.data.tools.filter(n=>n.type!=="tool_result").map(n=>this._normalizeToolCall(n,s,e.timestamp))}),t}_normalizeToolCall(e,s,t){if(e.type==="tool_use"){let n=this._computeStatus(e),r=e._startTime||t,a=e._matched?e._endTime||t:null;return{type:"tool_use",id:e.id,name:e.name,startTime:r,endTime:a,status:n,input:e.input||{},result:e.result||null,error:e.error||null,metadata:{source:s,matched:e._matched,duration:this._computeDuration(r,a)}}}if(e.name&&e.status){let n=t,r=e.status==="success"?"completed":e.status,a=r==="completed"||r==="error"?t:null;return{id:e.id||this._generateToolId(),name:e.name,startTime:n,endTime:a,status:r,input:e.input||{},result:e.isError?null:e.result||null,error:e.isError?e.result:null,metadata:{source:s,duration:this._computeDuration(n,a)}}}return console.warn("[EventNormalizer] Unknown tool format, applying fallback normalization",e),{id:e.id||this._generateToolId(),name:e.name||"unknown",startTime:t,endTime:null,status:"running",input:e.input||{},result:null,error:null,metadata:{source:s,fallback:!0}}}_computeStatus(e){return e.error?"error":e.result!==void 0&&e.result!==null&&e.result!==""?"completed":e._matched===!1?"running":e._matched?"completed":"running"}_computeDuration(e,s){if(!(!e||!s))try{let t=new Date(e),n=new Date(s);if(isNaN(t.getTime())||isNaN(n.getTime()))return;let r=n.getTime()-t.getTime();return r>=0?r:void 0}catch{return}}_generateToolId(){return`tool-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}_normalizeTimelineEvent(e){return e.type==="tool.execution_start"||e.type==="tool.execution_complete"?{...e,data:{...e.data,toolCallId:e.data?.toolCallId||e.data?.id,toolName:e.data?.toolName||e.data?.tool||e.data?.name,...e.data}}:(e.type?.startsWith("subagent."),e)}};rs.exports=Be});var He=w((Gr,ls)=>{var re=require("fs"),J=require("path"),Hn=require("readline"),{isValidSessionId:os,buildMetadata:Jn}=z(),is=Ve(),Gn=as(),We=class{constructor(e){e?(this.SESSION_DIR=e,this.sessionRepository=new is(e)):this.sessionRepository=new is,this.eventNormalizer=new Gn}async getAllSessions(e=null){return(await this.sessionRepository.findAll(e)).map(t=>t.toJSON())}async getPaginatedSessions(e=1,s=20,t=null){let r=(await this.sessionRepository.findAll(t)).map(l=>l.toJSON()),a=(e-1)*s,o=a+s;return{sessions:r.slice(a,o),totalSessions:r.length,currentPage:e,totalPages:Math.ceil(r.length/s),hasNextPage:o<r.length,hasPrevPage:e>1}}async getSessionById(e){if(!os(e))return null;let s=await this.sessionRepository.findById(e);if(s)return typeof s.toJSON=="function"?s.toJSON():s}async getSessionEvents(e,s=null){if(!os(e))return s?{events:[],total:0}:[];let t=await this.sessionRepository.findById(e);if(!t)return s?{events:[],total:0}:[];let n=this._getSourceAdapter(t.source),a=this.sessionRepository.sources.find(l=>l.type===t.source)?.dir||null;!a&&n&&(a=await n.resolveDir()),this.SESSION_DIR&&t.source==="copilot"&&(a=this.SESSION_DIR);let o=n&&!n.hasCustomPipeline?await n.resolveEventsFile(t,a):null,i=[];if(n?i=await n.readEvents(t,a)||[]:console.warn(`SessionService.getSessionEvents: No adapter found for source '${t.source}'. Returning no events.`),i.length>0&&(t.source==="claude"&&t.type==="directory"?i=i.filter(c=>c._subagent):i=i.filter(c=>!c._subagent)),i.sort((l,c)=>{let u=l.timestamp?new Date(l.timestamp).getTime():0,d=c.timestamp?new Date(c.timestamp).getTime():0;return u!==d?u-d:(l._fileIndex??0)-(c._fileIndex??0)}),i=i.filter(l=>l.type!=="file-history-snapshot"),i=i.map(l=>this._normalizeEvent(l,t.source)),n&&!n.hasCustomPipeline&&await this._mergeSubAgentEvents(i,o,e,t.source),n&&!n.hasCustomPipeline&&t.source==="copilot"?(this._matchCopilotToolCalls(i),this._mergeHookEvents(i),i=this._expandCopilotToTimelineFormat(i)):n&&!n.hasCustomPipeline&&t.source==="claude"?(this._matchClaudeToolResults(i),i=this._expandClaudeToTimelineFormat(i)):n&&!n.hasCustomPipeline&&t.source==="pi-mono"&&this._mergePiMonoToolResults(i),i=i.filter(l=>l.timestamp||l.snapshot?.timestamp?!0:(console.warn("[SessionService] Filtered event without timestamp:",l.type,l.id||l._fileIndex),!1)),i.forEach(l=>{l._fileIndex===999999&&l.timestamp&&delete l._fileIndex}),i=this.eventNormalizer.normalizeEvents(i,t.source),s&&typeof s.limit=="number"&&typeof s.offset=="number"){let l=i.length;return{events:i.slice(s.offset,s.offset+s.limit),total:l}}return i}async _mergeSubAgentEvents(e,s,t,n){let r,a=n==="claude"?new Set(e.map(o=>this._getClaudeSubagentMergeKey(o)).filter(Boolean)):null;if(n==="claude"){let o=this.sessionRepository.sources.find(i=>i.type==="claude");if(!o)return;try{let i=await re.promises.readdir(o.dir);for(let l of i){let c=J.join(o.dir,l,t,"subagents");try{if((await re.promises.stat(c)).isDirectory()){r=c;break}}catch{}}}catch(i){console.error("Error searching Claude subagents:",i);return}}else if(n==="copilot"&&s){let o=J.dirname(s);J.basename(s)==="events.jsonl"?r=J.join(o,"subagents"):r=J.join(o,t,"subagents")}if(r){try{if(!(await re.promises.stat(r)).isDirectory())return}catch{return}try{let i=(await re.promises.readdir(r)).filter(l=>l.startsWith("agent-")&&l.endsWith(".jsonl"));if(i.length===0)return;for(let l of i){let c=l.replace(".jsonl",""),u=J.join(r,l);try{let d=re.createReadStream(u,{encoding:"utf-8"}),f=Hn.createInterface({input:d,crlfDelay:1/0}),g=[];for await(let v of f){let D=v.trim();D&&g.push(D)}if(g.length===0)continue;let m=c.replace("agent-",""),y=m.toUpperCase(),S=`Sub-agent ${c}`;try{let v=JSON.parse(g[0]);if(v.agentId&&(m=v.agentId,y=`agent-${v.agentId}`),v.message?.content){let D=typeof v.message.content=="string"?v.message.content:JSON.stringify(v.message.content);S=D.length>100?D.slice(0,100)+"...":D}}catch{}let T=g.map((v,D)=>{try{let Z=JSON.parse(v);return Z._fileIndex=1e6+D,Z._subagent={id:c,name:m},Z}catch(Z){return console.error(`Error parsing sub-agent ${c} line ${D+1}:`,Z.message),null}}).filter(v=>v!==null);if(T.length===0)continue;let b=T.map(v=>this._normalizeEvent(v,n));if(a&&(b=b.filter(v=>{let D=this._getClaudeSubagentMergeKey(v);return D?a.has(D)?!1:(a.add(D),!0):!0})),b.length===0)continue;let x=b[0],F=b[b.length-1],me=x.timestamp||new Date().toISOString(),fe=F.timestamp||new Date().toISOString(),it={type:"subagent.started",id:`${c}-start`,timestamp:me,_fileIndex:x._fileIndex-1,_subagent:{id:c,name:m},data:{toolCallId:c,agentName:m,agentDisplayName:y,agentDescription:S}},Ns={type:"subagent.completed",id:`${c}-end`,timestamp:fe,_fileIndex:F._fileIndex+1,_subagent:{id:c,name:m},data:{toolCallId:c,result:`Sub-agent ${y} completed`}};e.push(it,...b,Ns)}catch(d){console.error(`Error reading sub-agent ${c}:`,d)}}e.sort((l,c)=>{let u=l.timestamp?new Date(l.timestamp).getTime():0,d=c.timestamp?new Date(c.timestamp).getTime():0;return u!==d?u-d:l._fileIndex-c._fileIndex})}catch(o){console.error("Error processing sub-agents:",o)}}}_getClaudeSubagentMergeKey(e){if(!e||e.type?.startsWith("subagent."))return null;let s=e.timestamp||e.snapshot?.timestamp;if(!s)return null;let t=e.uuid||e.id||"",n=e.parentUuid||e.parentId||"",r=e.data?.message||"",a=Array.isArray(e.data?.tools)?e.data.tools.map(o=>!o||typeof o!="object"?"":o.type==="tool_use"?`${o.type}:${o.id||""}:${o.name||""}`:o.type==="tool_result"?`${o.type}:${o.tool_use_id||""}`:`${o.type||"tool"}:${o.id||""}:${o.name||""}`).join("|"):"";return!t&&!n&&!r&&!a?null:JSON.stringify([e.type,s,t,n,r,a])}_matchClaudeToolResults(e){let s=new Map;e.forEach(t=>{t.data?.tools&&t.data.tools.forEach(n=>{n.type==="tool_result"&&(n.tool_use_id?s.set(n.tool_use_id,n):console.warn("[sessionService] tool_result missing tool_use_id:",n))})}),e.forEach(t=>{t.type==="user"&&Array.isArray(t.message?.content)&&t.message.content.length>0&&t.message.content.every(r=>r?.type==="tool_result")&&(t._isToolResultWrapper=!0)}),e.forEach(t=>{t.data?.tools&&(t.data.tools=t.data.tools.map(n=>{if(n.type==="tool_use"){let r=s.get(n.id);return r?{...n,result:r.content,_matched:!0}:{...n,_matched:!1}}return n}),t.type==="assistant"||t.type==="assistant.message"?t.data.tools=t.data.tools.filter(n=>n.type!=="tool_result"):(t.type==="user"||t.type==="user.message")&&t.data.tools.length>0&&t.data.tools.every(r=>r.type==="tool_result")&&(t._isToolResultWrapper=!0))})}_mergePiMonoToolResults(e){let s=new Set;e.forEach(n=>{if(n.type==="assistant.message"&&n.data.tools&&n.data.tools.length>0){let r=n.data.tools,a=[],o=n.id,i=!0;for(;i&&a.length<r.length;){i=!1;for(let l of e)if(l.type==="message"&&l.data.role==="toolResult"&&l.parentId===o&&!a.includes(l)){a.push(l),o=l.id,i=!0;break}}a.forEach((l,c)=>{if(c<r.length){let u=r[c];u.result=l.data.result,u.resultId=l.id,u.status="completed",s.add(l.id)}})}});let t=e.length;for(let n=e.length-1;n>=0;n--)e[n].type==="message"&&e[n].data.role==="toolResult"&&s.has(e[n].id)&&e.splice(n,1);s.size>0&&console.log(`[PI-MONO] Merged ${s.size} toolResult events into assistant messages (${t} \u2192 ${e.length} events)`)}_matchPiMonoToolResults_OLD(e){let s=new Set;e.forEach(n=>{if(n.type==="assistant.message"&&n.data.tools&&n.data.tools.length>0){let r=n.data.tools,a=[],o=n.id,i=!0;for(;i&&a.length<r.length;){i=!1;for(let l of e)if(l.type==="tool.result"&&l.parentId===o&&!a.includes(l)){a.push(l),o=l.id,i=!0;break}}a.forEach((l,c)=>{if(c<r.length){let u=r[c];u.status="completed",u._matched=!0,u.result=l.data.result,u.resultId=l.id,s.add(l.id)}})}});let t=e.length;for(let n=e.length-1;n>=0;n--)e[n].type==="tool.result"&&s.has(e[n].id)&&e.splice(n,1);s.size>0&&console.log(`[PI-MONO] Removed ${s.size} matched tool.result events (${t} \u2192 ${e.length} events)`)}_mergeHookEvents(e){let s=new Map;for(let t=0;t<e.length;t++){let n=e[t],r=n.data?.hookInvocationId;if(r){if(n.type==="hook.start")s.set(r,t);else if(n.type==="hook.end"){let a=s.get(r);if(a!==void 0){let o=e[a],i=n.data?.success!==!1;if(o.data.hookSuccess=i,o.data.hookError=n.data?.error||null,o.timestamp&&n.timestamp){let l=new Date(n.timestamp)-new Date(o.timestamp);o.data.hookDurationMs=l;let c=l<1e3?`${l}ms`:`${(l/1e3).toFixed(2)}s`;o.data.message&&(o.data.message+=`
|
|
10
|
+
**Duration:** ${c}`)}o.data.badgeLabel=i?"\u2713 HOOK":"\u2717 HOOK",o.data.badgeClass=i?"badge-tool":"badge-error",s.delete(r)}n._remove=!0}}}for(let t=e.length-1;t>=0;t--)e[t]._remove&&e.splice(t,1)}_matchCopilotToolCalls(e){let s=new Map;e.forEach(t=>{if(t.type==="tool.execution_start"){let n=t.data?.toolCallId;n&&s.set(n,{name:t.data.toolName,input:t.data.arguments||{},start:t})}else if(t.type==="tool.execution_complete"){let n=t.data?.toolCallId;if(n)if(s.has(n)){let r=s.get(n);r.complete=t,r.result=t.data?.result,r.status=t.data?.error?"error":"completed",r.error=t.data?.error}else console.warn(`[sessionService] Orphaned tool.execution_complete for toolCallId=${n}`),s.set(n,{name:t.data.toolName||"unknown",input:{},start:null,complete:t,result:t.data?.result,status:t.data?.error?"error":"completed",error:t.data?.error})}}),e.forEach(t=>{if(t.type==="assistant.message"&&t.data?.toolRequests){let n=[];t.data.toolRequests.forEach(r=>{let a=r.toolCallId;if(s.has(a)){let o=s.get(a);n.push({type:"tool_use",id:a,name:r.name||o.name,input:r.arguments||o.input,result:o.result,status:o.status||"running",error:o.error,_matched:!!o.complete,_startTime:o.start?.timestamp,_endTime:o.complete?.timestamp})}else n.push({type:"tool_use",id:a,name:r.name,input:r.arguments||{},status:"running",_matched:!1})}),n.length>0&&(t.data.tools=n)}})}_generateBadgeInfo(e){let s=e.type,t=e.data||{};if(s==="message"&&t.role==="toolResult"){e.data.badgeLabel="TOOL RESULT",e.data.badgeClass="badge-tool";return}if(s==="session.model_change"||s==="model.change"){e.data.badgeLabel="MODEL CHANGE",e.data.badgeClass="badge-session";return}if(s==="session.truncation"){e.data.badgeLabel="TRUNCATION",e.data.badgeClass="badge-truncation";return}if(s==="session.compaction_start"||s==="session.compaction_complete"||s==="compaction"){e.data.badgeLabel="COMPACTION",e.data.badgeClass="badge-compaction";return}if(s==="thinking.change"){e.data.badgeLabel="THINKING",e.data.badgeClass="badge-session";return}if(s==="system.notification"){e.data.badgeLabel="SYSTEM",e.data.badgeClass="badge-system";return}let r=(s||"").split(".")[0]||"unknown",o={user:{label:"USER",class:"badge-user"},assistant:{label:"ASSISTANT",class:"badge-assistant"},reasoning:{label:"REASONING",class:"badge-reasoning"},turn:{label:"TURN",class:"badge-turn"},tool:{label:"TOOL",class:"badge-tool"},subagent:{label:"SUBAGENT",class:"badge-subagent"},skill:{label:"SKILL",class:"badge-skill"},session:{label:"SESSION",class:"badge-session"},error:{label:"ERROR",class:"badge-error"},abort:{label:"ABORT",class:"badge-error"}}[r]||{label:r.toUpperCase(),class:"badge-info"};e.data.badgeLabel=o.label,e.data.badgeClass=o.class}_normalizeEvent(e,s){let t={...e};if(t.data=t.data||{},s==="copilot"){if(e.type==="user.message"&&e.data?.source==="system"){t.type="system.notification";let n=e.data.content||e.data.message||"",r=n.match(/<system_notification>([\s\S]*?)<\/system_notification>/);return t.data.message=r?r[1].trim():n.trim(),this._generateBadgeInfo(t),t}if(e.type==="request"){if(t.type="user",e.payload?.messages&&Array.isArray(e.payload.messages)){let n=e.payload.messages.find(r=>r.role==="user");n&&(t.message={role:"user",content:n.content||""})}}else if(e.type==="response"&&(t.type="assistant",e.payload?.content&&Array.isArray(e.payload.content))){let n=e.payload.content.filter(r=>r.type==="text");n.length>0&&(t.message={role:"assistant",content:n.map(r=>r.text).join(`
|
|
11
11
|
`)})}if(e.type==="assistant.message"&&e.data?.content&&e.data.content.trim()&&(t.data.message=e.data.content),e.type==="subagent.selected"&&Array.isArray(e.data?.tools)&&(t.data.allowedTools=e.data.tools,delete t.data.tools,(e.data.agentDisplayName||e.data.agentName)&&(t.data.message=`Agent: ${e.data.agentDisplayName||e.data.agentName}`,t.data.allowedTools.length>0&&t.data.allowedTools[0]!=="*"&&(t.data.message+=`
|
|
12
|
-
Tools: ${t.data.allowedTools.join(", ")}`))),e.type==="hook.start"){let
|
|
13
|
-
`)),t.data.badgeLabel="HOOK",t.data.badgeClass="badge-tool",this._generateBadgeInfo(t),t}if(e.type==="hook.end"){let
|
|
14
|
-
`),t.data.badgeLabel="HOOK END",t.data.badgeClass=
|
|
15
|
-
`)),
|
|
16
|
-
`))}
|
|
17
|
-
`))}return this._generateBadgeInfo(t),t}switch(e.type){case"user":case"assistant":if(e.message){if(e.message.content){let
|
|
12
|
+
Tools: ${t.data.allowedTools.join(", ")}`))),e.type==="hook.start"){let n=e.data||{},r=[];if(n.hookType&&r.push(`**Hook:** ${n.hookType}`),n.input?.toolName&&r.push(`**Tool:** ${n.input.toolName}`),n.input?.toolArgs&&Object.keys(n.input.toolArgs).length>0){let a=Object.entries(n.input.toolArgs).map(([o,i])=>`${o}: ${typeof i=="string"?i:JSON.stringify(i)}`).join(", ");r.push(`**Args:** ${a}`)}if(n.input?.toolResult?.textResultForLlm){let a=n.input.toolResult.textResultForLlm.slice(0,200);r.push(`**Result:** ${a}${n.input.toolResult.textResultForLlm.length>200?"\u2026":""}`)}return r.length>0&&(t.data.message=r.join(`
|
|
13
|
+
`)),t.data.badgeLabel="HOOK",t.data.badgeClass="badge-tool",this._generateBadgeInfo(t),t}if(e.type==="hook.end"){let n=e.data||{},r=[];return n.hookType&&r.push(`**Hook:** ${n.hookType}`),r.push(n.success?"**Status:** \u2713 success":"**Status:** \u2717 failed"),n.error&&r.push(`**Error:** ${n.error}`),t.data.message=r.join(`
|
|
14
|
+
`),t.data.badgeLabel="HOOK END",t.data.badgeClass=n.success?"badge-tool":"badge-error",this._generateBadgeInfo(t),t}return this._generateBadgeInfo(t),t}if(s==="pi-mono"){if(e.type==="message"){let{message:n}=e;if(n.role==="user"?t.type="user.message":n.role==="assistant"?t.type="assistant.message":n.role==="toolResult"&&(t.type="message"),t.data.role=n.role,Array.isArray(n.content)){let r=n.content.filter(a=>a.type==="text");if(r.length>0&&(t.data.message=r.map(a=>a.text).join(`
|
|
15
|
+
`)),n.role==="assistant"){let a=n.content.filter(o=>o.type==="toolCall");a.length>0&&(t.data.tools=a.map(o=>({type:"tool_use",id:o.id,name:o.name,input:o.arguments})))}n.role==="toolResult"&&(t.data.result=r.map(a=>a.text).join(`
|
|
16
|
+
`))}n.usage&&(t.usage=n.usage)}else if(e.type==="model_change")t.type="model.change",t.data={provider:e.provider,model:e.modelId},e.provider&&e.modelId?t.data.message=`Model changed to ${e.provider}/${e.modelId}`:e.modelId&&(t.data.message=`Model changed to ${e.modelId}`);else if(e.type==="thinking_level_change")t.type="thinking.change",t.data={level:e.thinkingLevel},e.thinkingLevel&&(t.data.message=`Thinking level: ${e.thinkingLevel}`);else if(e.type==="session"){t.data={cwd:e.cwd,version:e.version};let n=[];e.cwd&&n.push(`Working directory: ${e.cwd}`),e.version&&n.push(`Session version: ${e.version}`),n.length>0&&(t.data.message=n.join(`
|
|
17
|
+
`))}return this._generateBadgeInfo(t),t}switch(e.type){case"user":case"assistant":if(e.message){if(e.message.model&&(t.model=e.message.model),e.message.usage&&(t.usage=e.message.usage),e.message.content){let n=this._extractClaudeTextContent(e.message.content);n&&(t.data.message=n)}if(Array.isArray(e.message.content)){let n=e.message.content.filter(r=>r&&typeof r=="object"&&(r.type==="tool_use"||r.type==="tool_result"));n.length>0&&(t.data.tools=n.map(r=>r.type==="tool_use"?{type:"tool_use",id:r.id,name:r.name,input:r.input}:{type:"tool_result",tool_use_id:r.tool_use_id,content:r.content}))}t._originalMessage=e.message}break;case"file-history-snapshot":if(e.snapshot?.trackedFileBackups){let n=Object.entries(e.snapshot.trackedFileBackups);if(n.length>0){let r=n.map(([a,o])=>`${a} (v${o.version})`).join(`
|
|
18
18
|
`);t.data.message=`Tracked files:
|
|
19
|
-
${r}`}else t.data.message="No files tracked"}break;case"progress":if(e.data){let
|
|
20
|
-
`)),e.data.message?.message?.content&&Array.isArray(e.data.message.message.content)){let r=e.data.message.message.content.filter(
|
|
21
|
-
`)),t.data.badgeLabel="HOOK",t.data.badgeClass="badge-tool";break}case"hook.end":{let
|
|
22
|
-
`),t.data.badgeLabel="HOOK END",t.data.badgeClass=
|
|
23
|
-
`);s
|
|
24
|
-
`)}return""}
|
|
25
|
-
`):typeof r.message.content=="string"&&(i=r.message.content):r.data?.message&&(i=r.data.message),n.push({type:"assistant.turn_start",id:`${o}-start`,timestamp:a,parentId:r.parentId,uuid:r.uuid,data:{message:i,turnId:o},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex}),n.push({type:"assistant.message",id:o,timestamp:a,parentId:r.parentId,uuid:r.uuid,data:{message:i,tools:r.data?.tools||[]},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex+.05}),r.data?.tools&&r.data.tools.length>0&&r.data.tools.forEach((l,c)=>{l.start&&n.push({...l.start,_fileIndex:r._fileIndex+.1+c*.02}),l.complete&&n.push({...l.complete,_fileIndex:r._fileIndex+.15+c*.02})}),n.push({type:"assistant.turn_complete",id:`${o}-complete`,timestamp:a,parentId:o,uuid:r.uuid,data:{message:i},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex+.9});continue}n.push(r)}return n}_expandClaudeToTimelineFormat(e){let n=[],t=0;for(let s=0;s<e.length;s++){let r=e[s];if(r.type==="user"){t++,n.push({...r,type:"user.message",_turnNumber:t,data:{...r.data,message:r.data?.message||""}});continue}if(r.type==="assistant"){let o=r.id||`claude-assistant-${s}`,a=r.timestamp,i=r.data?.message||"";n.push({type:"assistant.turn_start",id:`${o}-start`,timestamp:a,parentId:r.parentId,data:{message:i,turnId:o},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex}),n.push({type:"assistant.message",id:o,timestamp:a,parentId:r.parentId,data:{message:i,tools:r.data?.tools||[]},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex+.05}),r.data?.tools&&r.data.tools.length>0&&r.data.tools.forEach((l,c)=>{l.type==="tool_use"&&(n.push({type:"tool.execution_start",id:`${l.id}-start`,timestamp:a,data:{toolCallId:l.id,toolName:l.name,arguments:l.input||{}},_synthetic:!0,_fileIndex:r._fileIndex+.1+c*.02}),l.result&&n.push({type:"tool.execution_complete",id:`${l.id}-complete`,timestamp:a,data:{toolCallId:l.id,toolName:l.name,result:l.result,isError:!1},_synthetic:!0,_fileIndex:r._fileIndex+.15+c*.02}))}),n.push({type:"assistant.turn_complete",id:`${o}-complete`,timestamp:a,parentId:o,data:{message:i},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex+.9});continue}n.push(r)}return n}_expandVsCodeToTimelineFormat(e){let n=[];for(let t=0;t<e.length;t++){let s=e[t];n.push(s),s.type==="assistant.message"&&s.data?.tools&&s.data.tools.length>0&&s.data.tools.forEach((r,o)=>{if(!r.id||!r.name)return;let a=r.startTime||s.timestamp,i=r.endTime||s.timestamp;n.push({type:"tool.execution_start",id:`${r.id}-start`,timestamp:a,parentId:s.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,arguments:r.input||{}},_synthetic:!0,_fileIndex:s._fileIndex?s._fileIndex+.1+o*.02:void 0}),n.push({type:"tool.execution_complete",id:`${r.id}-complete`,timestamp:i,parentId:r.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,result:r.result||null,error:r.error||(r.status==="error"?"Tool execution failed":null),isError:r.status==="error"},_synthetic:!0,_fileIndex:s._fileIndex?s._fileIndex+.15+o*.02:void 0})})}return n}_getSourceAdapter(e){let n=this.sessionRepository.registry||ce().registry;return n?.get?n.get(e):null}};ts.exports=Le});var Be=w((Rr,ss)=>{var $=require("fs").promises,R=require("path"),qn=require("os"),Ve=class{constructor(){this.knownTagsDir=R.join(qn.homedir(),".session-viewer"),this.knownTagsFilePath=R.join(this.knownTagsDir,"known-tags.json")}async ensureKnownTagsFile(){try{await $.access(this.knownTagsFilePath)}catch{await $.mkdir(this.knownTagsDir,{recursive:!0}),await $.writeFile(this.knownTagsFilePath,JSON.stringify([]),"utf8")}}async readKnownTagsFile(){await this.ensureKnownTagsFile();try{let e=await $.readFile(this.knownTagsFilePath,"utf8");return JSON.parse(e)}catch(e){return console.error("Error reading known tags file:",e),[]}}async writeKnownTagsFile(e){await this.ensureKnownTagsFile(),await $.writeFile(this.knownTagsFilePath,JSON.stringify(e,null,2),"utf8")}getSessionTagsFilePath(e){if(e.filePath){let n=R.dirname(e.filePath),t=R.basename(e.filePath,R.extname(e.filePath));return R.join(n,`${t}.tags.json`)}return e.directory?R.join(e.directory,"tags.json"):R.join(this.knownTagsDir,"session-tags",`${e.id}.tags.json`)}normalizeTag(e){return e.trim().toLowerCase().substring(0,30)}async getAllKnownTags(){return(await this.readKnownTagsFile()).sort()}async getSessionTags(e){let n=this.getSessionTagsFilePath(e);try{await $.access(n);let t=await $.readFile(n,"utf8");return JSON.parse(t)}catch{return[]}}async setSessionTags(e,n){if(!Array.isArray(n))throw new Error("Tags must be an array");let t=n.map(r=>this.normalizeTag(r)).filter(r=>r.length>0).filter((r,o,a)=>a.indexOf(r)===o);if(t.length>10)throw new Error("Maximum 10 tags per session");let s=this.getSessionTagsFilePath(e);if(t.length===0)try{await $.unlink(s)}catch{}else await $.mkdir(R.dirname(s),{recursive:!0}),await $.writeFile(s,JSON.stringify(t,null,2),"utf8"),await this.updateKnownTags(t);return t}async updateKnownTags(e){let t=[...await this.readKnownTagsFile(),...e],s=[...new Set(t)];await this.writeKnownTagsFile(s)}async addSessionTags(e,n){let s=[...await this.getSessionTags(e),...n];return await this.setSessionTags(e,s)}async removeSessionTags(e,n){let t=await this.getSessionTags(e),s=n.map(o=>this.normalizeTag(o)),r=t.filter(o=>!s.includes(o));return await this.setSessionTags(e,r)}async getMultipleSessionTags(e){let n={};for(let t of e)n[t.id]=await this.getSessionTags(t);return n}};ss.exports=Ve});var as=w((qr,os)=>{var Fn=ze(),{isValidSessionId:oe,buildMetadata:ns}=V(),{trackEvent:J,trackMetric:rs}=F(),Ln=require("adm-zip"),G=require("path"),q=require("fs"),Ue=class{constructor(e=null){this.sessionService=e||new Fn}async getHomepage(e,n){try{let t=await this.sessionService.getPaginatedSessions(1,20,"copilot"),s={};if(this.sessionService.sessionRepository&&this.sessionService.sessionRepository.sources)for(let o of this.sessionService.sessionRepository.sources)s[o.type]=o.dir;let r={sessions:t.sessions,hasMore:t.hasNextPage,totalSessions:t.totalSessions,sourceHints:JSON.stringify(s)};J("HomepageViewed",{sessionCount:t.totalSessions.toString(),sourceFilter:"copilot"}),n.render("index",r)}catch(t){console.error("Error loading sessions:",t),n.status(500).send("Error loading sessions")}}async getSessionDetail(e,n){try{let t=e.params.id;if(!oe(t))return n.status(400).json({error:"Invalid session ID"});let s=await this.sessionService.sessionRepository.findById(t);if(!s)return n.status(404).json({error:"Session not found"});let r=ns(s);try{let l=(await this.sessionService.getSessionEvents(t)).find(c=>c.type==="session.shutdown");if(l&&l.data){let c=l.data;r.usage={modelMetrics:c.modelMetrics||{},totalPremiumRequests:c.totalPremiumRequests||0,totalApiDurationMs:c.totalApiDurationMs||0,codeChanges:c.codeChanges||{linesAdded:0,linesRemoved:0,filesModified:[]},currentTokens:c.currentTokens||0,systemTokens:c.systemTokens||0,conversationTokens:c.conversationTokens||0,toolDefinitionsTokens:c.toolDefinitionsTokens||0}}}catch(i){console.error("Error extracting usage data:",i)}J("SessionViewed",{sessionId:t,source:s.source||"unknown",eventCount:(s.eventCount||r.totalEvents||0).toString(),duration:(s.duration||r.duration||0).toString(),model:s.model||r.model||"unknown",sessionStatus:s.status||r.status||"unknown"});let o=s.eventCount||r.totalEvents||0;o>0&&rs("SessionEventCount",o,{sessionId:t,source:s.source||"unknown"});let a=s.duration||r.duration||0;a>0&&rs("SessionDuration",a,{sessionId:t,source:s.source||"unknown"}),n.render("session-vue",{sessionId:t,events:[],metadata:r})}catch(t){console.error("Error loading session:",t),n.status(500).json({error:"Error loading session"})}}async getTimeAnalysis(e,n){try{let t=e.params.id;if(!oe(t))return n.status(400).json({error:"Invalid session ID"});let s=await this.sessionService.sessionRepository.findById(t);if(!s)return n.status(404).json({error:"Session not found"});let r=ns(s);J("TimeAnalysisViewed",{sessionId:t,turnCount:(r.totalEvents||0).toString()}),n.render("time-analyze",{sessionId:t,events:[],metadata:r})}catch(t){console.error("Error loading time analysis:",t),n.status(500).json({error:"Error loading analysis"})}}async getSessions(e,n){try{let t=e.query.page?parseInt(e.query.page):null,s=e.query.limit?parseInt(e.query.limit):null,r=e.query.source||null;if(t&&s){if(t<1||s<1||s>100)return n.status(400).json({error:"Invalid pagination parameters"});let o=await this.sessionService.getPaginatedSessions(t,s,r);J("SessionListLoaded",{page:t.toString(),limit:s.toString(),totalSessions:o.totalSessions.toString()}),n.set({"Cache-Control":"public, max-age=60"}),n.json(o)}else if(r&&s){let o=await this.sessionService.getAllSessions(r),a=o.slice(0,s);n.set({"Cache-Control":"public, max-age=60"}),n.json({sessions:a,hasMore:o.length>s,totalSessions:o.length})}else{let o=await this.sessionService.getAllSessions(r);n.set({"Cache-Control":"public, max-age=300"}),n.json(o)}}catch(t){console.error("Error loading sessions:",t),n.status(500).json({error:"Error loading sessions"})}}async loadMoreSessions(e,n){try{let t=parseInt(e.query.offset)||0,s=parseInt(e.query.limit)||20,r=e.query.source||null;if(t<0||s<1||s>50)return n.status(400).json({error:"Invalid parameters"});let o=Math.floor(t/s)+1,a=await this.sessionService.getPaginatedSessions(o,s,r);J("SessionListLoaded",{page:o.toString(),limit:s.toString(),totalSessions:a.totalSessions.toString()}),n.json({sessions:a.sessions,hasMore:a.hasNextPage,totalSessions:a.totalSessions})}catch(t){console.error("Error loading more sessions:",t),n.status(500).json({error:"Error loading more sessions"})}}async getSessionEvents(e,n){try{let t=e.params.id;if(!oe(t))return n.status(400).json({error:"Invalid session ID"});let s=e.query.limit!==void 0||e.query.offset!==void 0,r,o,a;if(s){if(r=parseInt(e.query.limit)||100,o=parseInt(e.query.offset)||0,r<1||r>1e3)return n.status(400).json({error:"Limit must be between 1 and 1000"});if(o<0)return n.status(400).json({error:"Offset must be non-negative"})}if(!await this.sessionService.sessionRepository.findById(t))return n.status(404).json({error:"Session not found"});s?a=await this.sessionService.getSessionEvents(t,{limit:r,offset:o}):a=await this.sessionService.getSessionEvents(t),n.set({"Cache-Control":"no-store",Vary:"Accept-Encoding"}),s?n.json({events:a.events,pagination:{total:a.total,limit:r,offset:o,hasMore:o+r<a.total}}):n.json(a)}catch(t){console.error("Error loading events:",t),n.status(500).json({error:"Error loading events"})}}async getTimeline(e,n){try{let t=e.params.id;if(!oe(t))return n.status(400).json({error:"Invalid session ID"});let s=await this.sessionService.getSessionById(t);if(!s)return n.status(404).json({error:"Session not found"});let r=await this.sessionService.getTimeline(t),o=require("crypto"),a=`${t}-timeline-${s.updatedAt||s.createdAt}`,i=o.createHash("md5").update(a).digest("hex");n.set({ETag:i,"Cache-Control":"private, max-age=300",Vary:"Accept-Encoding"}),n.json(r)}catch(t){console.error("Error loading timeline:",t),n.status(500).json({error:"Error loading timeline"})}}async exportSession(e,n){let t=e.params.id;if(!oe(t))return n.status(400).json({error:"Invalid session ID"});try{let s=await this.sessionService.sessionRepository.findById(t);if(!s)return n.status(404).json({error:"Session not found"});let r,o=!1;if(s.directory)try{(await q.promises.stat(s.directory)).isDirectory()&&(r=s.directory,o=!0)}catch{}if(!r&&s.filePath)try{await q.promises.access(s.filePath),r=s.filePath}catch{}if(!r){if(s.source==="copilot"){let l=this.sessionService.sessionRepository.sources.find(c=>c.type==="copilot");if(l){let c=G.join(l.dir,t);try{(await q.promises.stat(c)).isDirectory()?(r=c,o=!0):r=`${c}.jsonl`}catch{r=`${c}.jsonl`}}}else if(s.source==="claude"){let l=this.sessionService.sessionRepository.sources.find(c=>c.type==="claude");if(l){let c=await q.promises.readdir(G.join(l.dir,"projects"));for(let d of c){let p=G.join(l.dir,"projects",d,`${t}.jsonl`);try{await q.promises.access(p),r=p;break}catch{}}}}else if(s.source==="pi-mono"){let l=this.sessionService.sessionRepository.sources.find(c=>c.type==="pi-mono");if(l){let d=(await q.promises.readdir(l.dir)).find(p=>p.includes(t)&&p.endsWith(".jsonl"));d&&(r=G.join(l.dir,d))}}}if(!r)return n.status(404).json({error:"Session file not found"});try{await q.promises.access(r)}catch{return n.status(404).json({error:"Session file not accessible"})}let a=new Ln;if(o)a.addLocalFolder(r,t);else{let l=G.basename(r);a.addLocalFile(r,"",l);let c=Be(),p=new c().getSessionTagsFilePath(s);try{await q.promises.access(p),a.addLocalFile(p,"",G.basename(p))}catch{}}let i=a.toBuffer();n.setHeader("Content-Type","application/zip"),n.setHeader("Content-Disposition",`attachment; filename="session-${t}.zip"`),J("SessionExported",{sessionId:t}),n.send(i)}catch(s){console.error("Error exporting session:",s),n.status(500).json({error:"Error exporting session"})}}};os.exports=Ue});var ue=w((Fr,is)=>{var We=class{constructor(){this.activeProcesses=new Set,this.isShuttingDown=!1,this._setupCleanupHandlers()}register(e,n={}){let t={process:e,metadata:n,startTime:Date.now()};return this.activeProcesses.add(t),e.on("exit",()=>{this.activeProcesses.delete(t);let s=Date.now()-t.startTime;console.log(`\u{1F504} Process exited (${n.name||"unknown"}): ${s}ms`)}),t}killAll(){console.log(`\u{1F6D1} Killing ${this.activeProcesses.size} active processes...`);for(let{process:e,metadata:n}of this.activeProcesses)try{e.killed||(e.kill("SIGTERM"),console.log(` \u2713 Killed ${n.name||e.pid}`))}catch(t){console.error(` \u2717 Failed to kill ${n.name||e.pid}:`,t.message)}this.activeProcesses.clear()}getActiveCount(){return this.activeProcesses.size}_setupCleanupHandlers(){let e=(n,t=0)=>{this.isShuttingDown||(this.isShuttingDown=!0,console.log(`
|
|
26
|
-
\u{1F4DB} Received ${
|
|
19
|
+
${r}`}else t.data.message="No files tracked"}break;case"progress":if(e.data){let n=[];if(e.data.hookName&&n.push(`Hook: ${e.data.hookName}`),e.data.hookEvent&&n.push(`Event: ${e.data.hookEvent}`),e.data.command&&n.push(`Command: ${e.data.command}`),n.length>0&&(t.data.message=n.join(`
|
|
20
|
+
`)),e.data.message?.message?.content&&Array.isArray(e.data.message.message.content)){let r=e.data.message.message.content.filter(a=>a&&typeof a=="object"&&(a.type==="tool_use"||a.type==="tool_result"));r.length>0&&(t.data.tools=r.map(a=>a.type==="tool_use"?{type:"tool_use",id:a.id,name:a.name,input:a.input}:{type:"tool_result",tool_use_id:a.tool_use_id,content:a.content}))}}break;case"hook.start":{let n=e.data||{},r=[];if(n.hookType&&r.push(`**Hook:** ${n.hookType}`),n.input?.toolName&&r.push(`**Tool:** ${n.input.toolName}`),n.input?.toolArgs&&Object.keys(n.input.toolArgs).length>0){let a=Object.entries(n.input.toolArgs).map(([o,i])=>`${o}: ${typeof i=="string"?i:JSON.stringify(i)}`).join(", ");r.push(`**Args:** ${a}`)}if(n.input?.toolResult?.textResultForLlm){let a=n.input.toolResult.textResultForLlm.slice(0,200);r.push(`**Result:** ${a}${n.input.toolResult.textResultForLlm.length>200?"\u2026":""}`)}r.length>0&&(t.data.message=r.join(`
|
|
21
|
+
`)),t.data.badgeLabel="HOOK",t.data.badgeClass="badge-tool";break}case"hook.end":{let n=e.data||{},r=[];n.hookType&&r.push(`**Hook:** ${n.hookType}`),r.push(n.success?"**Status:** \u2713 success":"**Status:** \u2717 failed"),n.error&&r.push(`**Error:** ${n.error}`),t.data.message=r.join(`
|
|
22
|
+
`),t.data.badgeLabel="HOOK END",t.data.badgeClass=n.success?"badge-tool":"badge-error";break}default:e.data?.message&&!t.data.message&&(t.data.message=e.data.message)}return this._generateBadgeInfo(t),t}_extractClaudeTextContent(e){if(typeof e=="string")return e;if(Array.isArray(e)){let s=[];for(let t of e)if(t.type==="text")s.push(t.text);else if(t.type==="tool_result"){if(typeof t.content=="string")s.push(t.content);else if(Array.isArray(t.content)){let n=t.content.filter(r=>r.type==="text").map(r=>r.text).join(`
|
|
23
|
+
`);n&&s.push(n)}}return s.join(`
|
|
24
|
+
`)}return""}_getClaudeUsageNumber(e){return typeof e=="number"&&Number.isFinite(e)?e:0}_getClaudeCacheWriteTokens(e){let s=this._getClaudeUsageNumber(e?.cache_creation_input_tokens);return s>0?s:!e?.cache_creation||typeof e.cache_creation!="object"?0:Object.values(e.cache_creation).reduce((t,n)=>t+this._getClaudeUsageNumber(n),0)}_getClaudeUsagePayload(e){return e?.usage&&typeof e.usage=="object"?e.usage:e?.toolUseResult?.usage&&typeof e.toolUseResult.usage=="object"?e.toolUseResult.usage:e?.message?.usage&&typeof e.message.usage=="object"?e.message.usage:null}_getClaudeEventTotalTokens(e){return this._getClaudeUsageNumber(e?.totalTokens)||this._getClaudeUsageNumber(e?.toolUseResult?.totalTokens)}_getClaudeEventDurationMs(e){return this._getClaudeUsageNumber(e?.totalDurationMs)||this._getClaudeUsageNumber(e?.toolUseResult?.totalDurationMs)}_getClaudeEventModel(e){return e?.model||e?.message?.model||e?._originalMessage?.model||null}_resolveClaudeUsageModel(e,s){return this._getClaudeEventModel(e)||s.get(e?.sourceToolAssistantUUID)||s.get(e?.parentUuid)||s.get(e?.uuid)||"unknown"}_indexClaudeRelatedUsageEvents(e){let s=new Map;for(let t of e){if(!t?._isToolResultWrapper||!this._getClaudeUsagePayload(t)&&this._getClaudeEventTotalTokens(t)===0)continue;let n=new Set([t.sourceToolAssistantUUID,t.parentUuid].filter(r=>typeof r=="string"&&r.length>0));for(let r of n)s.has(r)||s.set(r,[]),s.get(r).push(t)}return s}_extractClaudeUsageData(e){let s={},t=new Map;for(let r of e){let a=this._getClaudeEventModel(r);a&&r?.uuid&&t.set(r.uuid,a)}let n=0;for(let r of e){let a=[r,...Array.isArray(r._relatedUsageEvents)?r._relatedUsageEvents:[]];for(let o of a){let i=this._getClaudeUsagePayload(o)||{},l=this._getClaudeUsageNumber(i.cache_read_input_tokens),c=this._getClaudeCacheWriteTokens(i),u=this._getClaudeUsageNumber(i.input_tokens),d=this._getClaudeUsageNumber(i.output_tokens),f=this._getClaudeEventTotalTokens(o),g=u+l+c;if(g===0&&d===0&&f>0&&(g=Math.max(f-d,0)),g===0&&d===0)continue;let m=this._resolveClaudeUsageModel(o,t);s[m]||(s[m]={requests:{count:0},usage:{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheWriteTokens:0}}),s[m].requests.count+=1,s[m].usage.inputTokens+=g,s[m].usage.outputTokens+=d,s[m].usage.cacheReadTokens+=l,s[m].usage.cacheWriteTokens+=c,n+=this._getClaudeEventDurationMs(o)}}return Object.keys(s).length===0?null:{modelMetrics:s,totalPremiumRequests:0,totalApiDurationMs:n,codeChanges:{linesAdded:0,linesRemoved:0,filesModified:[]},currentTokens:0,systemTokens:0,conversationTokens:0,toolDefinitionsTokens:0}}extractUsageData(e){if(!Array.isArray(e)||e.length===0)return null;let s=e.find(t=>t.type==="session.shutdown");if(s&&s.data){let t=s.data;return{modelMetrics:t.modelMetrics||{},totalPremiumRequests:t.totalPremiumRequests||0,totalApiDurationMs:t.totalApiDurationMs||0,codeChanges:t.codeChanges||{linesAdded:0,linesRemoved:0,filesModified:[]},currentTokens:t.currentTokens||0,systemTokens:t.systemTokens||0,conversationTokens:t.conversationTokens||0,toolDefinitionsTokens:t.toolDefinitionsTokens||0}}return this._extractClaudeUsageData(e)}async getSessionWithEvents(e){let s=await this.getSessionById(e);if(!s)return null;let t=await this.getSessionEvents(e),n=Jn(s),r=t.find(o=>o.type==="session.start");r?.data?.selectedModel&&(n.model=r.data.selectedModel);let a=t.find(o=>o.type==="session.model_change");if(a?.data&&(n.model=a.data.newModel||a.data.model),t.length){let o=t[t.length-1];o?.timestamp&&(n.updated=o.timestamp)}if(t.length){let o=t[0];o?.timestamp&&(n.created=o.timestamp)}return n.usage=this.extractUsageData(t),{session:s,events:t,metadata:n}}async getTimeline(e){let s=await this.getSessionById(e);if(!s)return null;let t=await this.getSessionEvents(e),n=this._getSourceAdapter(s.source);if(n){let r=n.buildTimeline(t,s);if(r&&(r.turns?.length>0||Object.keys(r.summary||{}).length>0))return r}return s.source==="copilot"?this._buildCopilotTimeline(t,s):s.source==="claude"?this._buildClaudeTimeline(t,s):s.source==="pi-mono"?this._buildPiMonoTimeline(t,s):{turns:[],summary:{}}}_buildPiMonoTimeline(e,s){let t=[],n=0;for(let o=0;o<e.length;o++){let i=e[o];if(i.type==="user.message"){n++;let l={id:`turn-${n}`,type:"user-request",message:i.data.message||"",startTime:i.timestamp,endTime:i.timestamp,assistantTurns:[],subagents:[]},c=o+1,u=0;for(;c<e.length&&e[c].type!=="user.message";){let d=e[c];if(d.type==="assistant.message"){u++,l.endTime=d.timestamp;let f={id:`assistant-${u}`,startTime:d.timestamp,endTime:d.timestamp,tools:[]};if(d.data.tools&&Array.isArray(d.data.tools))for(let g of d.data.tools)f.tools.push({name:g.name,startTime:d.timestamp,endTime:d.timestamp,status:g.status||"completed",input:g.input,result:g.result});l.assistantTurns.push(f)}c++}t.push(l)}}let r=t.reduce((o,i)=>o+i.assistantTurns.reduce((l,c)=>l+c.tools.length,0),0),a={totalTurns:t.length,totalAssistantTurns:t.reduce((o,i)=>o+i.assistantTurns.length,0),totalTools:r,totalSubagents:0,startTime:e[0]?.timestamp,endTime:e[e.length-1]?.timestamp};return{turns:t,summary:a}}_buildCopilotTimeline(e,s){let t=[],n=null,r=0;for(let o of e)if(o.type==="assistant.turn_start")r++,n={id:`turn-${r}`,type:"assistant-turn",message:o.data.message||"",startTime:o.timestamp,endTime:null,tools:[],subagents:[]};else if(o.type==="assistant.turn_complete"&&n)n.endTime=o.timestamp,t.push(n),n=null;else if(o.type==="tool.execution_start"&&n){let i={name:o.data.tool||o.data.name,startTime:o.timestamp,endTime:null,status:"running",input:o.data.arguments||o.data.input};n.tools.push(i)}else if(o.type==="tool.execution_complete"&&n){let i=n.tools.find(l=>l.name===(o.data.tool||o.data.name)&&!l.endTime);i&&(i.endTime=o.timestamp,i.status=o.data?.error||o.data?.isError?"error":"completed",i.result=o.data?.result)}n&&(n.endTime=e[e.length-1]?.timestamp,t.push(n));let a={totalTurns:t.length,totalTools:t.reduce((o,i)=>o+i.tools.length,0),totalSubagents:0,startTime:e[0]?.timestamp,endTime:e[e.length-1]?.timestamp};return{turns:t,summary:a}}_buildClaudeTimeline(e,s){return this._buildPiMonoTimeline(e,s)}_expandPiMonoToCopilotFormat(e){let s=[],t=0,n=0;for(let r=0;r<e.length;r++){let a=e[r];if(a.type!=="user.message"&&a.type!=="assistant.message"){s.push(a);continue}if(a.type==="user.message"){t++,s.push({...a,_turnNumber:t});continue}if(a.type==="assistant.message"){let o=a.data.tools||[],i=a.timestamp,l=`pi-turn-${r}`;s.push({type:"assistant.turn_start",id:`${l}-start`,timestamp:i,parentId:a.parentId,data:{message:a.data.message||"",model:a.data.model,tools:o.length>0?o:void 0},_synthetic:!0,_turnNumber:t,_fileIndex:a._fileIndex}),s.push({...a,_fileIndex:a._fileIndex+.05}),o.forEach((c,u)=>{let d=`pi-tool-${n++}`,f=i,g=i;s.push({type:"tool.execution_start",id:`${d}-start`,timestamp:f,parentId:l,data:{toolCallId:d,toolName:c.name,tool:c.name,arguments:c.input||{}},_synthetic:!0,_fileIndex:a._fileIndex+.1+u*.01}),s.push({type:"tool.execution_complete",id:`${d}-complete`,timestamp:g,parentId:d,data:{toolCallId:d,toolName:c.name,tool:c.name,result:c.result,error:c.status==="error"?"Tool execution failed":null,isError:c.status==="error"},_synthetic:!0,_fileIndex:a._fileIndex+.15+u*.01})}),s.push({type:"assistant.turn_complete",id:`${l}-complete`,timestamp:a.timestamp,parentId:l,data:{message:a.data.message||""},_synthetic:!0,_turnNumber:t,_fileIndex:a._fileIndex+.9})}}return s}_expandVsCodeEvents(e){let s=[],t=[],n=null,r=null,a=0,o=null,i=null,l=()=>{t.length!==0&&(s.push({type:"assistant.message",id:`vscode-tools-${a}`,timestamp:r,parentId:n,data:{message:"",content:"",tools:t,subAgentId:o,subAgentName:i},_synthetic:!0}),t=[],o=null,i=null)};for(let c=0;c<e.length;c++){let u=e[c];if(u.type==="tool.invocation"){let d=u.data?.subAgentId||null;t.length>0&&d!==o&&l(),t.length===0&&(n=u.parentId,r=u.timestamp,a=c,o=d,i=u.data?.subAgentName||null),u.data?.tool&&t.push(u.data.tool)}else l(),s.push(u)}return l(),s}_expandCopilotToTimelineFormat(e){let s=[],t=0;for(let n=0;n<e.length;n++){let r=e[n];if(r.type==="user"){t++,s.push({...r,type:"user.message",_turnNumber:t,data:{...r.data,message:r.message?.content||r.data?.message||""}});continue}if(r.type==="assistant"){let a=r.uuid||`copilot-assistant-${n}`,o=r.timestamp,i="";r.message?.content?Array.isArray(r.message.content)?i=r.message.content.filter(l=>l&&l.type==="text").map(l=>l.text).join(`
|
|
25
|
+
`):typeof r.message.content=="string"&&(i=r.message.content):r.data?.message&&(i=r.data.message),s.push({type:"assistant.turn_start",id:`${a}-start`,uuid:r.uuid,timestamp:o,parentId:r.parentId,data:{message:i,turnId:a},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex}),s.push({type:"assistant.message",id:a,uuid:r.uuid,timestamp:o,parentId:r.parentId,data:{message:i,tools:r.data?.tools||[]},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex+.05}),r.data?.tools&&r.data.tools.length>0&&r.data.tools.forEach((l,c)=>{l.start&&s.push({...l.start,_fileIndex:r._fileIndex+.1+c*.02}),l.complete&&s.push({...l.complete,_fileIndex:r._fileIndex+.15+c*.02})}),s.push({type:"assistant.turn_complete",id:`${a}-complete`,uuid:r.uuid,timestamp:o,parentId:a,data:{message:i},_synthetic:!0,_turnNumber:t,_fileIndex:r._fileIndex+.9});continue}s.push(r)}return s}_expandClaudeToTimelineFormat(e){let s=[],t=0,n=this._indexClaudeRelatedUsageEvents(e);for(let r=0;r<e.length;r++){let a=e[r];if(a.type==="user"){t++,s.push({...a,type:"user.message",_turnNumber:t,data:{...a.data,message:a.data?.message||""}});continue}if(a.type==="assistant"){let o=a.id||`claude-assistant-${r}`,i=a.timestamp,l=a.uuid?n.get(a.uuid)||[]:[],c=a.data?.message||"";s.push({type:"assistant.turn_start",id:`${o}-start`,uuid:a.uuid,timestamp:i,parentId:a.parentId,data:{message:c,turnId:o},_synthetic:!0,_turnNumber:t,_fileIndex:a._fileIndex}),s.push({type:"assistant.message",id:o,uuid:a.uuid,timestamp:i,parentId:a.parentId,model:a.model,usage:a.usage,data:{message:c,tools:a.data?.tools||[]},_synthetic:!0,_turnNumber:t,_fileIndex:a._fileIndex+.05}),a.data?.tools&&a.data.tools.length>0&&a.data.tools.forEach((u,d)=>{u.type==="tool_use"&&(s.push({type:"tool.execution_start",id:`${u.id}-start`,timestamp:i,data:{toolCallId:u.id,toolName:u.name,arguments:u.input||{}},_synthetic:!0,_fileIndex:a._fileIndex+.1+d*.02}),u.result&&s.push({type:"tool.execution_complete",id:`${u.id}-complete`,timestamp:i,data:{toolCallId:u.id,toolName:u.name,result:u.result,isError:!1},_synthetic:!0,_fileIndex:a._fileIndex+.15+d*.02}))}),s.push({type:"assistant.turn_complete",id:`${o}-complete`,uuid:a.uuid,timestamp:i,parentId:o,model:a.model,_relatedUsageEvents:l.map(u=>({uuid:u.uuid,parentUuid:u.parentUuid,sourceToolAssistantUUID:u.sourceToolAssistantUUID,usage:this._getClaudeUsagePayload(u),totalTokens:this._getClaudeEventTotalTokens(u),totalDurationMs:this._getClaudeEventDurationMs(u)})),data:{message:c},_synthetic:!0,_turnNumber:t,_fileIndex:a._fileIndex+.9});continue}s.push(a)}return s}_expandVsCodeToTimelineFormat(e){let s=[];for(let t=0;t<e.length;t++){let n=e[t];s.push(n),n.type==="assistant.message"&&n.data?.tools&&n.data.tools.length>0&&n.data.tools.forEach((r,a)=>{if(!r.id||!r.name)return;let o=r.startTime||n.timestamp,i=r.endTime||n.timestamp;s.push({type:"tool.execution_start",id:`${r.id}-start`,timestamp:o,parentId:n.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,arguments:r.input||{}},_synthetic:!0,_fileIndex:n._fileIndex?n._fileIndex+.1+a*.02:void 0}),s.push({type:"tool.execution_complete",id:`${r.id}-complete`,timestamp:i,parentId:r.id,data:{toolCallId:r.id,toolName:r.name,tool:r.name,result:r.result||null,error:r.error||(r.status==="error"?"Tool execution failed":null),isError:r.status==="error"},_synthetic:!0,_fileIndex:n._fileIndex?n._fileIndex+.15+a*.02:void 0})})}return s}_getSourceAdapter(e){let s=this.sessionRepository.registry||ce().registry;return s?.get?s.get(e):null}};ls.exports=We});var Ge=w((Kr,cs)=>{var O=require("fs").promises,R=require("path"),Kn=require("os"),Je=class{constructor(){this.knownTagsDir=R.join(Kn.homedir(),".session-viewer"),this.knownTagsFilePath=R.join(this.knownTagsDir,"known-tags.json")}async ensureKnownTagsFile(){try{await O.access(this.knownTagsFilePath)}catch{await O.mkdir(this.knownTagsDir,{recursive:!0}),await O.writeFile(this.knownTagsFilePath,JSON.stringify([]),"utf8")}}async readKnownTagsFile(){await this.ensureKnownTagsFile();try{let e=await O.readFile(this.knownTagsFilePath,"utf8");return JSON.parse(e)}catch(e){return console.error("Error reading known tags file:",e),[]}}async writeKnownTagsFile(e){await this.ensureKnownTagsFile(),await O.writeFile(this.knownTagsFilePath,JSON.stringify(e,null,2),"utf8")}getSessionTagsFilePath(e){if(e.filePath){let s=R.dirname(e.filePath),t=R.basename(e.filePath,R.extname(e.filePath));return R.join(s,`${t}.tags.json`)}return e.directory?R.join(e.directory,"tags.json"):R.join(this.knownTagsDir,"session-tags",`${e.id}.tags.json`)}normalizeTag(e){return e.trim().toLowerCase().substring(0,30)}async getAllKnownTags(){return(await this.readKnownTagsFile()).sort()}async getSessionTags(e){let s=this.getSessionTagsFilePath(e);try{await O.access(s);let t=await O.readFile(s,"utf8");return JSON.parse(t)}catch{return[]}}async setSessionTags(e,s){if(!Array.isArray(s))throw new Error("Tags must be an array");let t=s.map(r=>this.normalizeTag(r)).filter(r=>r.length>0).filter((r,a,o)=>o.indexOf(r)===a);if(t.length>10)throw new Error("Maximum 10 tags per session");let n=this.getSessionTagsFilePath(e);if(t.length===0)try{await O.unlink(n)}catch{}else await O.mkdir(R.dirname(n),{recursive:!0}),await O.writeFile(n,JSON.stringify(t,null,2),"utf8"),await this.updateKnownTags(t);return t}async updateKnownTags(e){let t=[...await this.readKnownTagsFile(),...e],n=[...new Set(t)];await this.writeKnownTagsFile(n)}async addSessionTags(e,s){let n=[...await this.getSessionTags(e),...s];return await this.setSessionTags(e,n)}async removeSessionTags(e,s){let t=await this.getSessionTags(e),n=s.map(a=>this.normalizeTag(a)),r=t.filter(a=>!n.includes(a));return await this.setSessionTags(e,r)}async getMultipleSessionTags(e){let s={};for(let t of e)s[t.id]=await this.getSessionTags(t);return s}};cs.exports=Je});var ms=w((Yr,ps)=>{var Yn=He(),{isValidSessionId:ae,buildMetadata:us}=z(),{trackEvent:G,trackMetric:ds}=U(),Zn=require("adm-zip"),K=require("path"),q=require("fs"),Ke=class{constructor(e=null){this.sessionService=e||new Yn}async getHomepage(e,s){try{let t=await this.sessionService.getPaginatedSessions(1,20,"copilot"),n={};if(this.sessionService.sessionRepository&&this.sessionService.sessionRepository.sources)for(let a of this.sessionService.sessionRepository.sources)n[a.type]=a.dir;let r={sessions:t.sessions,hasMore:t.hasNextPage,totalSessions:t.totalSessions,sourceHints:JSON.stringify(n)};G("HomepageViewed",{sessionCount:t.totalSessions.toString(),sourceFilter:"copilot"}),s.render("index",r)}catch(t){console.error("Error loading sessions:",t),s.status(500).send("Error loading sessions")}}async getSessionDetail(e,s){try{let t=e.params.id;if(!ae(t))return s.status(400).json({error:"Invalid session ID"});let n=await this.sessionService.sessionRepository.findById(t);if(!n)return s.status(404).json({error:"Session not found"});let r=us(n);try{let i=await this.sessionService.getSessionEvents(t),l=this.sessionService.extractUsageData(i);l&&(r.usage=l)}catch(i){console.error("Error extracting usage data:",i)}G("SessionViewed",{sessionId:t,source:n.source||"unknown",eventCount:(n.eventCount||r.totalEvents||0).toString(),duration:(n.duration||r.duration||0).toString(),model:n.model||r.model||"unknown",sessionStatus:n.status||r.status||"unknown"});let a=n.eventCount||r.totalEvents||0;a>0&&ds("SessionEventCount",a,{sessionId:t,source:n.source||"unknown"});let o=n.duration||r.duration||0;o>0&&ds("SessionDuration",o,{sessionId:t,source:n.source||"unknown"}),s.render("session-vue",{sessionId:t,events:[],metadata:r})}catch(t){console.error("Error loading session:",t),s.status(500).json({error:"Error loading session"})}}async getTimeAnalysis(e,s){try{let t=e.params.id;if(!ae(t))return s.status(400).json({error:"Invalid session ID"});let n=await this.sessionService.sessionRepository.findById(t);if(!n)return s.status(404).json({error:"Session not found"});let r=us(n);G("TimeAnalysisViewed",{sessionId:t,turnCount:(r.totalEvents||0).toString()}),s.render("time-analyze",{sessionId:t,events:[],metadata:r})}catch(t){console.error("Error loading time analysis:",t),s.status(500).json({error:"Error loading analysis"})}}async getSessions(e,s){try{let t=e.query.page?parseInt(e.query.page):null,n=e.query.limit?parseInt(e.query.limit):null,r=e.query.source||null;if(t&&n){if(t<1||n<1||n>100)return s.status(400).json({error:"Invalid pagination parameters"});let a=await this.sessionService.getPaginatedSessions(t,n,r);G("SessionListLoaded",{page:t.toString(),limit:n.toString(),totalSessions:a.totalSessions.toString()}),s.set({"Cache-Control":"public, max-age=60"}),s.json(a)}else if(r&&n){let a=await this.sessionService.getAllSessions(r),o=a.slice(0,n);s.set({"Cache-Control":"public, max-age=60"}),s.json({sessions:o,hasMore:a.length>n,totalSessions:a.length})}else{let a=await this.sessionService.getAllSessions(r);s.set({"Cache-Control":"public, max-age=300"}),s.json(a)}}catch(t){console.error("Error loading sessions:",t),s.status(500).json({error:"Error loading sessions"})}}async loadMoreSessions(e,s){try{let t=parseInt(e.query.offset)||0,n=parseInt(e.query.limit)||20,r=e.query.source||null;if(t<0||n<1||n>50)return s.status(400).json({error:"Invalid parameters"});let a=Math.floor(t/n)+1,o=await this.sessionService.getPaginatedSessions(a,n,r);G("SessionListLoaded",{page:a.toString(),limit:n.toString(),totalSessions:o.totalSessions.toString()}),s.json({sessions:o.sessions,hasMore:o.hasNextPage,totalSessions:o.totalSessions})}catch(t){console.error("Error loading more sessions:",t),s.status(500).json({error:"Error loading more sessions"})}}async getSessionEvents(e,s){try{let t=e.params.id;if(!ae(t))return s.status(400).json({error:"Invalid session ID"});let n=e.query.limit!==void 0||e.query.offset!==void 0,r,a,o;if(n){if(r=parseInt(e.query.limit)||100,a=parseInt(e.query.offset)||0,r<1||r>1e3)return s.status(400).json({error:"Limit must be between 1 and 1000"});if(a<0)return s.status(400).json({error:"Offset must be non-negative"})}if(!await this.sessionService.sessionRepository.findById(t))return s.status(404).json({error:"Session not found"});n?o=await this.sessionService.getSessionEvents(t,{limit:r,offset:a}):o=await this.sessionService.getSessionEvents(t),s.set({"Cache-Control":"no-store",Vary:"Accept-Encoding"}),n?s.json({events:o.events,pagination:{total:o.total,limit:r,offset:a,hasMore:a+r<o.total}}):s.json(o)}catch(t){console.error("Error loading events:",t),s.status(500).json({error:"Error loading events"})}}async getTimeline(e,s){try{let t=e.params.id;if(!ae(t))return s.status(400).json({error:"Invalid session ID"});let n=await this.sessionService.getSessionById(t);if(!n)return s.status(404).json({error:"Session not found"});let r=await this.sessionService.getTimeline(t),a=require("crypto"),o=`${t}-timeline-${n.updatedAt||n.createdAt}`,i=a.createHash("md5").update(o).digest("hex");s.set({ETag:i,"Cache-Control":"private, max-age=300",Vary:"Accept-Encoding"}),s.json(r)}catch(t){console.error("Error loading timeline:",t),s.status(500).json({error:"Error loading timeline"})}}async exportSession(e,s){let t=e.params.id;if(!ae(t))return s.status(400).json({error:"Invalid session ID"});try{let n=await this.sessionService.sessionRepository.findById(t);if(!n)return s.status(404).json({error:"Session not found"});let r,a=!1;if(n.directory)try{(await q.promises.stat(n.directory)).isDirectory()&&(r=n.directory,a=!0)}catch{}if(!r&&n.filePath)try{await q.promises.access(n.filePath),r=n.filePath}catch{}if(!r){if(n.source==="copilot"){let l=this.sessionService.sessionRepository.sources.find(c=>c.type==="copilot");if(l){let c=K.join(l.dir,t);try{(await q.promises.stat(c)).isDirectory()?(r=c,a=!0):r=`${c}.jsonl`}catch{r=`${c}.jsonl`}}}else if(n.source==="claude"){let l=this.sessionService.sessionRepository.sources.find(c=>c.type==="claude");if(l){let c=await q.promises.readdir(K.join(l.dir,"projects"));for(let u of c){let d=K.join(l.dir,"projects",u,`${t}.jsonl`);try{await q.promises.access(d),r=d;break}catch{}}}}else if(n.source==="pi-mono"){let l=this.sessionService.sessionRepository.sources.find(c=>c.type==="pi-mono");if(l){let u=(await q.promises.readdir(l.dir)).find(d=>d.includes(t)&&d.endsWith(".jsonl"));u&&(r=K.join(l.dir,u))}}}if(!r)return s.status(404).json({error:"Session file not found"});try{await q.promises.access(r)}catch{return s.status(404).json({error:"Session file not accessible"})}let o=new Zn;if(a)o.addLocalFolder(r,t);else{let l=K.basename(r);o.addLocalFile(r,"",l);let c=Ge(),d=new c().getSessionTagsFilePath(n);try{await q.promises.access(d),o.addLocalFile(d,"",K.basename(d))}catch{}}let i=o.toBuffer();s.setHeader("Content-Type","application/zip"),s.setHeader("Content-Disposition",`attachment; filename="session-${t}.zip"`),G("SessionExported",{sessionId:t}),s.send(i)}catch(n){console.error("Error exporting session:",n),s.status(500).json({error:"Error exporting session"})}}};ps.exports=Ke});var de=w((Zr,fs)=>{var Ye=class{constructor(){this.activeProcesses=new Set,this.isShuttingDown=!1,this._setupCleanupHandlers()}register(e,s={}){let t={process:e,metadata:s,startTime:Date.now()};return this.activeProcesses.add(t),e.on("exit",()=>{this.activeProcesses.delete(t);let n=Date.now()-t.startTime;console.log(`\u{1F504} Process exited (${s.name||"unknown"}): ${n}ms`)}),t}killAll(){console.log(`\u{1F6D1} Killing ${this.activeProcesses.size} active processes...`);for(let{process:e,metadata:s}of this.activeProcesses)try{e.killed||(e.kill("SIGTERM"),console.log(` \u2713 Killed ${s.name||e.pid}`))}catch(t){console.error(` \u2717 Failed to kill ${s.name||e.pid}:`,t.message)}this.activeProcesses.clear()}getActiveCount(){return this.activeProcesses.size}_setupCleanupHandlers(){let e=(s,t=0)=>{this.isShuttingDown||(this.isShuttingDown=!0,console.log(`
|
|
26
|
+
\u{1F4DB} Received ${s}, shutting down gracefully...`),this.killAll(),setTimeout(()=>{process.exit(t)},1e3))};process.on("SIGTERM",()=>e("SIGTERM",0)),process.on("SIGINT",()=>e("SIGINT",0)),process.on("uncaughtException",s=>{console.error("\u{1F4A5} Uncaught exception:",s),e("uncaughtException",1)})}},Ze="__copilotSessionViewerProcessManager";globalThis[Ze]||(globalThis[Ze]=new Ye);fs.exports=globalThis[Ze]});var Ss=w((Xr,ys)=>{var _=require("fs").promises,gs=require("fs"),j=require("path"),Xn=require("os"),{spawn:Qn}=require("child_process"),hs=L(),er=de(),Xe=class{constructor(){}_getToolConfig(e,s){let t={copilot:{name:"Copilot",cli:"copilot",args:(n,r)=>["--config-dir",n,"--yolo","-p",r],cwd:s},vscode:{name:"Copilot",cli:"copilot",args:(n,r)=>["--config-dir",n,"--yolo","-p",r],cwd:s},claude:{name:"Claude Code",cli:"claude",args:(n,r)=>["-p",r,"--dangerously-skip-permissions"],cwd:s},"pi-mono":{name:"Pi",cli:"pi",args:(n,r)=>["-p",r],cwd:s}};return t[e]||t.copilot}async generateInsight(e,s,t="copilot",n=!1){let r=j.join(s,`${e}.agent-review.md`),a=j.join(s,`${e}.agent-review.md.lock`),o=j.join(s,"events.jsonl");try{await _.access(o)}catch{try{o=j.join(s,`${e}.jsonl`),await _.access(o)}catch{let u=(await _.readdir(s)).find(d=>d.endsWith(`_${e}.jsonl`));u&&(o=j.join(s,u))}}let i=this._getToolConfig(t,s),l=i.name;if(!n)try{let c=await _.readFile(r,"utf-8"),u=await _.stat(r);return{status:"completed",report:c,generatedAt:u.mtime}}catch{}try{await _.writeFile(a,JSON.stringify({sessionId:e,startTime:new Date().toISOString(),pid:process.pid}),{flag:"wx"})}catch(c){if(c.code==="EEXIST")try{let u=JSON.parse(await _.readFile(a,"utf-8")),d=await _.stat(a),f=Date.now()-d.mtime.getTime();if(f<hs.INSIGHT_TIMEOUT_MS)return{status:"generating",report:`# Generating ${l} Insight...
|
|
27
27
|
|
|
28
|
-
Another request is currently generating this insight. Please wait.`,startedAt:
|
|
28
|
+
Another request is currently generating this insight. Please wait.`,startedAt:d.birthtime,lastUpdate:d.mtime,ageMs:Date.now()-d.birthtime.getTime()};console.log(`\u26A0\uFE0F Removing stale lock file (${Math.floor(f/1e3)}s old)`),await _.unlink(a),await _.writeFile(a,JSON.stringify({sessionId:e,startTime:new Date().toISOString(),pid:process.pid}),{flag:"wx"})}catch(u){throw new Error("Failed to acquire lock for insight generation",{cause:u})}else throw c}try{await _.access(o)}catch(c){throw await _.unlink(a),new Error("Events file not found",{cause:c})}if(n)try{await _.unlink(r)}catch{}return await this._spawnAnalysisProcess(s,o,r,a,i),{status:"generating",report:`# Generating ${l} Insight...
|
|
29
29
|
|
|
30
|
-
Analysis in progress. Please wait.`,startedAt:new Date}}async _spawnAnalysisProcess(e,
|
|
30
|
+
Analysis in progress. Please wait.`,startedAt:new Date}}async _spawnAnalysisProcess(e,s,t,n,r){let a=j.basename(e),o=j.join(Xn.tmpdir(),`agent-review-${a}-${Date.now()}`);await _.mkdir(o,{recursive:!0});let i=this._buildPrompt(t,s),l=j.join(e,`${a}.agent-review.md.tmp`),c=r.cli,u=r.args(o,i);console.log(`\u{1F916} Starting ${r.name} analysis: ${c} ${u.slice(0,2).join(" ")}...`),console.log(`\u{1F4CB} Args count: ${u.length}, prompt length: ${i.length} chars`);let d=Qn(c,u,{env:{...process.env},cwd:e,stdio:["pipe","pipe","pipe"]});if(er.register(d,{name:`insight-${a}`}),r.cli==="copilot"){let S=gs.createReadStream(s);d.stdin.on("error",T=>{T.code==="EPIPE"?S.destroy():console.error("\u274C stdin error:",T)}),S.pipe(d.stdin)}else d.stdin.end();let f=gs.createWriteStream(l);d.stdout.pipe(f);let g=[],m=0,y=64*1024;d.stderr.on("data",S=>{m<y&&(g.push(S),m+=S.length)}),d.on("close",async S=>{try{f.end();let T=Buffer.concat(g).toString("utf-8").slice(0,y);if(console.log(`\u{1F4CB} ${r.name} process exited with code ${S}`),T&&console.log(`\u{1F4CB} ${r.name} stderr:`,T.substring(0,500)),S!==0)console.error(`\u274C ${r.name} CLI failed (code ${S}):`,T),await _.writeFile(t,`# \u274C Generation Failed
|
|
31
31
|
|
|
32
32
|
Exit code: ${S}
|
|
33
33
|
|
|
34
34
|
\`\`\`
|
|
35
35
|
${T||"(no error output)"}
|
|
36
36
|
\`\`\`
|
|
37
|
-
`,"utf-8");else{let
|
|
38
|
-
${
|
|
39
|
-
**IMPORTANT**: This directory may contain multiple .jsonl files. You MUST analyze ONLY the file named \`${
|
|
37
|
+
`,"utf-8");else{let b=!1;try{let x=await _.readFile(t,"utf-8");x&&x.trim().length>50&&(b=!0,console.log(`\u2705 Insight generated for session ${a} (agent wrote directly)`))}catch{}if(!b){let x=await _.readFile(l,"utf-8");x=this._cleanReport(x),await _.writeFile(t,x,"utf-8"),console.log(`\u2705 Insight generated for session ${a} (cleaned from stdout)`)}}await _.unlink(l).catch(()=>{}),await _.unlink(n).catch(()=>{}),await _.rm(o,{recursive:!0,force:!0}).catch(()=>{}),await _.rm(j.join(e,".output"),{recursive:!0,force:!0}).catch(()=>{})}catch(T){console.error("\u274C Error finalizing insight:",T),await _.unlink(n).catch(()=>{}),await _.rm(o,{recursive:!0,force:!0}).catch(()=>{})}}),d.on("error",async S=>{console.error(`\u274C Failed to spawn ${r.name}:`,S),await _.unlink(n).catch(()=>{}),await _.rm(o,{recursive:!0,force:!0}).catch(()=>{})})}_buildPrompt(e,s){let t=j.dirname(e),n=j.basename(s),r=`${t}/.output`;return`You are an expert AI agent evaluator. The current working directory is an AI coding agent session folder. It contains the raw session data from an agent run.
|
|
38
|
+
${n.includes("_")?`
|
|
39
|
+
**IMPORTANT**: This directory may contain multiple .jsonl files. You MUST analyze ONLY the file named \`${n}\`. Do NOT read or analyze any other .jsonl files in this directory.
|
|
40
40
|
`:""}
|
|
41
41
|
**Step 1 \u2014 Discover session files.** Run \`ls -la\` to see what's available, then note which files exist:
|
|
42
|
-
- \`${
|
|
42
|
+
- \`${n}\` \u2014 the main session event log (JSONL, one JSON event per line). Primary data source. May be large. **This is the ONLY events file you should analyze.**
|
|
43
43
|
- \`plan.md\` \u2014 the agent's plan (if it exists).
|
|
44
44
|
- \`workspace.yaml\` \u2014 workspace configuration (if it exists).
|
|
45
45
|
- Any other relevant files.
|
|
46
46
|
|
|
47
47
|
**Step 2 \u2014 Spawn 3 sub-agents for parallel analysis.** First create the working directory: \`mkdir -p ${r}\`. Then use the Task tool to launch ALL of the following sub-agents simultaneously (in a single message with multiple Task tool calls). Each sub-agent should:
|
|
48
|
-
- Read \`${
|
|
48
|
+
- Read \`${n}\` from \`${t}\` (use Bash: \`cat\`, \`jq\`, or \`python3\` to parse) **\u2014 ONLY this file, ignore others**
|
|
49
49
|
- Read other session files as needed
|
|
50
50
|
- Write its findings to an intermediate file in \`${r}/\`
|
|
51
51
|
- Return a summary of its findings
|
|
@@ -96,9 +96,9 @@ Be brutally honest. Generic advice like "add error handling" is useless \u2014 a
|
|
|
96
96
|
|
|
97
97
|
IMPORTANT CONSTRAINTS:
|
|
98
98
|
- Be precise and concise. Every sentence must carry data or actionable insight \u2014 no filler, no fluff.
|
|
99
|
-
- The entire report MUST be under 3000 characters (including markdown formatting). Cut ruthlessly if needed.`}_cleanReport(e){e=e.replace(/<thinking>[\s\S]*?<\/thinking>/g,""),e=e.replace(/^(Let me analyze|I'll analyze|Analyzing|Here's my analysis of|I need the session data).*$/gm,"");let
|
|
100
|
-
`),
|
|
99
|
+
- The entire report MUST be under 3000 characters (including markdown formatting). Cut ruthlessly if needed.`}_cleanReport(e){e=e.replace(/<thinking>[\s\S]*?<\/thinking>/g,""),e=e.replace(/^(Let me analyze|I'll analyze|Analyzing|Here's my analysis of|I need the session data).*$/gm,"");let s=/^## 🎯\s*Effectiveness Score/m,t=[...e.matchAll(new RegExp(s.source,"gm"))];if(t.length>0){let n=t[t.length-1];e=e.slice(n.index)}else{let n=e.match(/^(## [🎯🔧🔄⚡💡#])/mu);if(n)e=e.slice(n.index);else{let r=e.split(`
|
|
100
|
+
`),a=[],o=!1;for(let i of r){if(/^● /.test(i)){o=!0;continue}if(/^ {2}\$ /.test(i)){o=!0;continue}if(/^ {2}└ /.test(i)){o=!1;continue}if(!/^\(\+\d+ lines?\)/.test(i)&&!/^ {2}└ \d+ lines/.test(i)){if(/^● Asked user:/.test(i)){o=!0;continue}if(/^ {2}└ User responded:/.test(i)){o=!1;continue}o&&/\S/.test(i)&&!/^ {2}/.test(i)&&(o=!1),!o&&a.push(i)}}e=a.join(`
|
|
101
101
|
`)}}return e=e.replace(/\n{3,}/g,`
|
|
102
102
|
|
|
103
|
-
`).trim(),e}async getInsightStatus(e,
|
|
104
|
-
`),m=0,g=0,f=0;for(let S of p){let T=S.trim().match(/^\s*(\d+)\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.+)$/);if(T){let v=parseInt(T[1]),j=T[2];m+=v,g++;let L=(j.match(/\//g)||[]).length;f=Math.max(f,L)}}if(m>o)return await h.promises.unlink(t),n.status(400).json({error:`Uncompressed size too large (${Math.round(m/1024/1024)}MB > ${o/1024/1024}MB)`});if(g>a)return await h.promises.unlink(t),n.status(400).json({error:`Too many files in archive (${g} > ${a})`});if(f>i)return await h.promises.unlink(t),n.status(400).json({error:`Directory nesting too deep (${f} > ${i})`});let y=Ye("unzip",["-q",t,"-d",s]);gs.register(y,{name:"unzip-import"}),y.on("close",async S=>{let T;try{if(await h.promises.unlink(t),S!==0)return await h.promises.rm(s,{recursive:!0,force:!0}),n.status(500).json({error:"Failed to extract zip file"});let v=await h.promises.readdir(s);if(v.length===0)return await h.promises.rm(s,{recursive:!0,force:!0}),n.status(400).json({error:"Empty zip file"});if(T=v[0],!K(T))return await h.promises.rm(s,{recursive:!0,force:!0}),n.status(400).json({error:"Invalid session directory name in zip file"});let j=I.join(s,T),L=I.join(this.SESSION_DIR,T),pe=I.join(j,"events.jsonl");try{await h.promises.access(pe)}catch{return await h.promises.rm(s,{recursive:!0,force:!0}),n.status(400).json({error:"Invalid session structure (no events.jsonl)"})}if(h.existsSync(L))return await h.promises.rm(s,{recursive:!0,force:!0}),n.status(409).json({error:"Session already exists"});await h.promises.rename(j,L),await h.promises.rm(s,{recursive:!0,force:!0});let me=await h.promises.stat(t).catch(()=>({size:0}));fs("SessionImported",{format:"copilot",fileSize:me.size.toString()}),n.json({success:!0,sessionId:T})}catch(v){console.error("Error importing session:",v),Ze(v,{operation:"importSession",sessionId:T||"unknown"}),await h.promises.rm(s,{recursive:!0,force:!0}).catch(()=>{}),n.status(500).json({error:"Error importing session"})}}),y.on("error",async S=>{console.error("Error extracting zip:",S),Ze(S,{operation:"importSession_unzip"}),await h.promises.unlink(t).catch(()=>{}),await h.promises.rm(s,{recursive:!0,force:!0}).catch(()=>{}),n.status(500).json({error:"Failed to extract zip file"})})}catch(t){console.error("Error processing upload:",t),Ze(t,{operation:"importSession_upload"}),e.file&&await h.promises.unlink(e.file.path).catch(()=>{}),n.status(500).json({error:"Error processing upload"})}}getUploadMiddleware(){return this.upload.single("zipFile")}async _detectFormat(e){try{let n=await h.promises.readdir(e);if(n.length===0)return null;let t=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z_([a-zA-Z0-9_-]+)\.jsonl$/;for(let r of n){let o=r.match(t);if(o)return{format:"pi-mono",sessionId:o[1],fileName:r,extractDir:e}}for(let r of n){let o=I.join(e,r);if((await h.promises.stat(o)).isDirectory()){let i=I.join(o,"events.jsonl");if(h.existsSync(i))return{format:"copilot",sessionId:r,directoryName:r,extractDir:e}}}let s=/^([a-zA-Z0-9_-]+)\.jsonl$/;for(let r of n){let o=I.join(e,r);if((await h.promises.stat(o)).isFile()){let i=r.match(s);if(i){let l=i[1],c=I.join(e,l),d=h.existsSync(c);return{format:"claude",sessionId:l,fileName:r,hasDirectory:d,directoryName:d?l:void 0,extractDir:e}}}}return null}catch(n){return console.error("Error detecting format:",n),null}}async _importCopilotSession(e,n){try{let{sessionId:t,directoryName:s}=e;if(!K(t))return{success:!1,error:"Invalid session ID",statusCode:400};let r=I.join(n,s),o=I.join(this.SESSION_DIRS.copilot,t),a=I.join(r,"events.jsonl");return h.existsSync(a)?h.existsSync(o)?{success:!1,error:"Session already exists",statusCode:409}:(await h.promises.rename(r,o),await h.promises.writeFile(I.join(o,".imported"),""),{success:!0,sessionId:t,format:"copilot"}):{success:!1,error:"Invalid session structure (no events.jsonl)",statusCode:400}}catch(t){return console.error("Error importing Copilot session:",t),{success:!1,error:`Error importing Copilot session: ${t.message}`,statusCode:500}}}async _importClaudeSession(e,n,t){try{let{sessionId:s,fileName:r,hasDirectory:o,directoryName:a}=e;if(!K(s))return{success:!1,error:"Invalid session ID",statusCode:400};let i=t.query.project||"imported-sessions",l=I.join(this.SESSION_DIRS.claude,i);await h.promises.mkdir(l,{recursive:!0});let c=I.join(n,r),d=I.join(l,r);if(await h.promises.rename(c,d),o&&a){let p=I.join(n,a),m=I.join(l,a);await h.promises.rename(p,m)}return{success:!0,sessionId:s,format:"claude",project:i}}catch(s){return console.error("Error importing Claude session:",s),{success:!1,error:`Error importing Claude session: ${s.message}`,statusCode:500}}}async _importPiMonoSession(e,n,t){try{let{sessionId:s,fileName:r}=e;if(!K(s))return{success:!1,error:"Invalid session ID",statusCode:400};let o=t.query.project||"imported-sessions",a=I.join(this.SESSION_DIRS["pi-mono"],o);await h.promises.mkdir(a,{recursive:!0});let i=I.join(n,r),l=I.join(a,r);return await h.promises.rename(i,l),{success:!0,sessionId:s,format:"pi-mono",project:o}}catch(s){return console.error("Error importing Pi-Mono session:",s),{success:!1,error:`Error importing Pi-Mono session: ${s.message}`,statusCode:500}}}async _importByFormat(e,n,t){if(!K(e.sessionId))return{success:!1,error:"Invalid session ID",statusCode:400};switch(e.format){case"copilot":return await this._importCopilotSession(e,n);case"claude":return await this._importClaudeSession(e,n,t);case"pi-mono":return await this._importPiMonoSession(e,n,t);default:return{success:!1,error:`Unsupported format: ${e.format}`,statusCode:400}}}async _findSessionLocation(e,n=null){try{let t=n?[n,...Object.keys(this.SESSION_DIRS).filter(s=>s!==n)]:Object.keys(this.SESSION_DIRS);for(let s of t){let r=this.SESSION_DIRS[s];if(s==="copilot"){let o=I.join(r,e);if(h.existsSync(o)){let a=I.join(o,"events.jsonl");if(h.existsSync(a))return{source:"copilot",sessionId:e,sessionPath:o,baseDir:r}}}else if(s==="claude"){if(h.existsSync(r)){let o=await h.promises.readdir(r);for(let a of o){let i=I.join(r,a);if((await h.promises.stat(i)).isDirectory()){let c=I.join(i,`${e}.jsonl`);if(h.existsSync(c))return{source:"claude",sessionId:e,sessionFile:c,projectPath:i,project:a,baseDir:r}}}}}else if(s==="pi-mono"&&h.existsSync(r)){let o=await h.promises.readdir(r);for(let a of o){let i=I.join(r,a);if((await h.promises.stat(i)).isDirectory()){let c=await h.promises.readdir(i),d=new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z_${e}\\.jsonl$`);for(let p of c)if(d.test(p))return{source:"pi-mono",sessionId:e,fileName:p,sessionFile:I.join(i,p),projectPath:i,project:a,baseDir:r}}}}}return null}catch(t){return console.error("Error finding session location:",t),null}}};hs.exports=Xe});var _s=w((Br,ws)=>{var Kn=Be(),Yn=qe(),{isValidSessionId:Ss}=V(),{trackEvent:Zn}=F(),Qe=class{constructor(e=null,n=null){this.tagService=e||new Kn,this.sessionRepository=n||new Yn}async getAllTags(e,n){try{let t=await this.tagService.getAllKnownTags();n.json({tags:t})}catch(t){console.error("Error getting all tags:",t),n.status(500).json({error:"Error loading tags"})}}async getSessionTags(e,n){try{let t=e.params.id;if(!Ss(t))return n.status(400).json({error:"Invalid session ID"});let s=await this.sessionRepository.findById(t);if(!s)return n.status(404).json({error:"Session not found"});let r=await this.tagService.getSessionTags(s);n.json({tags:r})}catch(t){console.error("Error getting session tags:",t),n.status(500).json({error:"Error loading session tags"})}}async setSessionTags(e,n){try{let t=e.params.id,{tags:s}=e.body;if(!Ss(t))return n.status(400).json({error:"Invalid session ID"});if(!Array.isArray(s))return n.status(400).json({error:"Tags must be an array"});if(s.length>10)return n.status(400).json({error:"Maximum 10 tags per session"});for(let a of s){if(typeof a!="string"||a.trim().length===0)return n.status(400).json({error:"Tags must be non-empty strings"});if(a.length>30)return n.status(400).json({error:"Tag length must not exceed 30 characters"})}let r=await this.sessionRepository.findById(t);if(!r)return n.status(404).json({error:"Session not found"});let o=await this.tagService.setSessionTags(r,s);Zn("TagUpdated",{sessionId:t,tagCount:o.length.toString()}),n.json({tags:o})}catch(t){if(console.error("Error setting session tags:",t),t.message==="Maximum 10 tags per session")return n.status(400).json({error:t.message});if(t.message==="Session must have a directory field")return n.status(400).json({error:"Session does not support tagging"});n.status(500).json({error:"Error saving session tags"})}}};ws.exports=Qe});var bs=w((Ur,Es)=>{var de=require("express"),Is=require("path"),Ts=require("compression"),Xn=require("helmet"),Qn=z(),{requestTimeout:er,developmentCors:tr,errorHandler:sr,notFoundHandler:nr,telemetryLocals:rr}=ct(),or=as(),ar=ms(),ir=ys(),lr=_s();function cr(u={}){let e=de();e.set("etag",!1);let n=new or(u.sessionService),t=new ar(u.insightService,u.sessionService),s=new ir,r=new lr(u.tagService);return e.use((o,a,i)=>{a.setHeader("Content-Security-Policy","default-src 'self'; style-src 'self' 'unsafe-inline' https: http:; font-src 'self' https: http:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: http:; img-src 'self' data: https: http:; connect-src 'self' https: http:"),i()}),e.use(Xn({contentSecurityPolicy:!1,hsts:!1,referrerPolicy:!1,crossOriginEmbedderPolicy:!1,crossOriginOpenerPolicy:!1,crossOriginResourcePolicy:!1})),e.use(Ts({level:1,threshold:1024,filter:(o,a)=>o.path.includes("/events")&&a.getHeader("Content-Type")?.includes("application/json")?!1:Ts.filter(o,a)})),e.use(de.json({limit:"1mb"})),e.use(de.urlencoded({extended:!0})),e.use(er),e.use(rr),Qn.NODE_ENV==="development"&&e.use(tr),e.use("/public",de.static(Is.join(__dirname,"../public"))),e.set("view engine","ejs"),e.set("views",Is.join(__dirname,"../views")),e.get("/",n.getHomepage.bind(n)),e.get("/session/:id",n.getSessionDetail.bind(n)),e.get("/session/:id/time-analyze",n.getTimeAnalysis.bind(n)),e.get("/session/:id/export",n.exportSession.bind(n)),e.get("/api/sessions/load-more",n.loadMoreSessions.bind(n)),e.get("/api/sessions",n.getSessions.bind(n)),e.get("/api/sessions/:id/events",n.getSessionEvents.bind(n)),e.get("/api/sessions/:id/timeline",n.getTimeline.bind(n)),e.get("/api/tags",r.getAllTags.bind(r)),e.get("/api/sessions/:id/tags",r.getSessionTags.bind(r)),e.put("/api/sessions/:id/tags",r.setSessionTags.bind(r)),e.get("/session/:id/share",s.shareSession.bind(s)),e.post("/session/import",(o,a,i)=>s.getUploadMiddleware()(o,a,i),s.importSession.bind(s)),e.post("/session/:id/insight",t.generateInsight.bind(t)),e.get("/session/:id/insight",t.getInsightStatus.bind(t)),e.delete("/session/:id/insight",t.deleteInsight.bind(t)),e.use(nr),e.use(sr),e}Es.exports=cr});F();var ur=bs(),et=z(),dr=ue(),vs=ur();module.exports=vs;if(require.main===module){let u=vs.listen(et.PORT,()=>{console.log(`\u{1F680} Copilot Session Viewer running at http://localhost:${et.PORT}`),console.log(`\u{1F527} Environment: ${et.NODE_ENV}`),console.log(`\u26A1 Active processes: ${dr.getActiveCount()}`)});process.on("SIGTERM",()=>{console.log("\u{1F4DB} SIGTERM received, closing server..."),u.close(()=>{console.log("\u2705 Server closed")})})}
|
|
103
|
+
`).trim(),e}async getInsightStatus(e,s,t="copilot"){return await this._getStatusForSource(e,s)}async _getStatusForSource(e,s){let t=j.join(s,`${e}.agent-review.md`),n=j.join(s,`${e}.agent-review.md.lock`),r=j.join(s,`${e}.agent-review.md.tmp`);try{let a=await _.readFile(t,"utf-8"),o=await _.stat(t);return{status:"completed",report:a,generatedAt:o.mtime}}catch{try{await _.access(n);let o=await _.stat(n),i=Date.now()-o.birthtime.getTime(),l=null;try{l=await _.readFile(r,"utf-8")}catch{}return i>=hs.INSIGHT_TIMEOUT_MS?{status:"timeout",log:l,startedAt:o.birthtime,lastUpdate:o.mtime,ageMs:i}:{status:"generating",log:l,startedAt:o.birthtime,lastUpdate:o.mtime,ageMs:i}}catch{return{status:"not_started"}}}}async deleteInsight(e,s,t="copilot"){let n=j.join(s,`${e}.agent-review.md`);try{return await _.unlink(n),{success:!0}}catch(r){if(r.code==="ENOENT")return{success:!0,message:"Insight file not found"};throw r}}};ys.exports=Xe});var _s=w((Qr,ws)=>{var tr=Ss(),{isValidSessionId:Qe}=z(),{trackEvent:et,trackMetric:sr,trackException:nr}=U(),tt=class{constructor(e=null,s=null){if(e?this.insightService=e:this.insightService=new tr,s)this.sessionService=s;else{let t=He();this.sessionService=new t}}_getGenerateInsightErrorResponse(e){if(e instanceof Error){if(e.message==="Events file not found")return{status:400,body:{error:e.message}};if(e.message==="Failed to acquire lock for insight generation")return{status:503,body:{error:e.message}};if(e.message)return{status:500,body:{error:e.message}}}return{status:500,body:{error:"Error generating insight"}}}async generateInsight(e,s){try{let t=e.params.id,n=e.body?.force===!0;if(!Qe(t))return s.status(400).json({error:"Invalid session ID"});let r=await this.sessionService.getSessionById(t);if(!r)return s.status(404).json({error:"Session not found"});if(!r.directory)return s.status(400).json({error:"Session directory not available"});let a=Date.now(),o=await this.insightService.generateInsight(r.id,r.directory,r.source,n),i=Date.now()-a;et("InsightGenerated",{sessionId:t,source:r.source||"unknown",durationMs:i.toString()}),sr("InsightGenerationTime",i,{sessionId:t,source:r.source||"unknown"}),s.json(o)}catch(t){console.error("Error generating insight:",t),nr(t,{sessionId:e.params.id,operation:"generateInsight"});let n=this._getGenerateInsightErrorResponse(t);s.status(n.status).json(n.body)}}async getInsightStatus(e,s){try{let t=e.params.id;if(!Qe(t))return s.status(400).json({error:"Invalid session ID"});let n=await this.sessionService.getSessionById(t);if(!n)return s.status(404).json({error:"Session not found"});if(!n.directory)return s.status(400).json({error:"Session directory not available"});let r=await this.insightService.getInsightStatus(n.id,n.directory,n.source);r.status==="ready"&&r.report&&et("InsightViewed",{sessionId:t}),s.json(r)}catch(t){console.error("Error getting insight status:",t),s.status(500).json({error:"Error getting insight status"})}}async deleteInsight(e,s){try{let t=e.params.id;if(!Qe(t))return s.status(400).json({error:"Invalid session ID"});let n=await this.sessionService.getSessionById(t);if(!n)return s.status(404).json({error:"Session not found"});if(!n.directory)return s.status(400).json({error:"Session directory not available"});let r=await this.insightService.deleteInsight(n.id,n.directory,n.source);et("InsightDeleted",{sessionId:t}),s.json(r)}catch(t){console.error("Error deleting insight:",t),s.status(500).json({error:"Error deleting insight"})}}};ws.exports=tt});var bs=w((ea,Es)=>{var h=require("fs"),I=require("path"),oe=require("os"),rr=require("multer"),{spawn:st}=require("child_process"),{isValidSessionId:Y}=z(),{trackEvent:Is,trackException:nt}=U(),Ts=de(),ar=L(),rt=class{constructor(){this.SESSION_DIR=process.env.SESSION_DIR||I.join(oe.homedir(),".copilot","session-state"),this.uploadDir=process.env.UPLOAD_DIR||I.join(oe.tmpdir(),"copilot-session-uploads"),this.SESSION_DIRS={copilot:this.SESSION_DIR,claude:I.join(oe.homedir(),".claude","projects"),"pi-mono":I.join(oe.homedir(),".pi","agent","sessions")},this.upload=this.createMulterInstance()}createMulterInstance(){return rr({dest:this.uploadDir,limits:{fileSize:ar.MAX_UPLOAD_SIZE},fileFilter:(e,s,t)=>{let n=s.originalname.toLowerCase().endsWith(".zip"),r=s.mimetype==="application/zip"||s.mimetype==="application/x-zip-compressed";if(!n||!r)return t(new Error("Only .zip files are allowed"));t(null,!0)}})}async shareSession(e,s){try{let t=e.params.id;if(!Y(t))return s.status(400).json({error:"Invalid session ID"});let n=I.join(this.SESSION_DIR,t);try{await h.promises.access(n)}catch{return s.status(404).json({error:"Session not found"})}let r=I.join(oe.tmpdir(),`session-${t}.zip`),a=st("zip",["-r","-q",r,t],{cwd:this.SESSION_DIR});Ts.register(a,{name:`zip-${t}`}),a.on("close",o=>{if(o!==0)return s.status(500).json({error:"Failed to create zip file"});Is("SessionShared",{sessionId:t}),s.download(r,`session-${t}.zip`,i=>{h.promises.unlink(r).catch(()=>{}),i&&console.error("Error sending zip:",i)})}),a.on("error",o=>{console.error("Error creating zip:",o),s.status(500).json({error:"Failed to create zip file"})})}catch(t){console.error("Error sharing session:",t),s.status(500).json({error:"Error sharing session"})}}async importSession(e,s){try{if(!e.file)return s.status(400).json({error:"No file uploaded"});let t=e.file.path,n=I.join(this.uploadDir,`extract-${Date.now()}`);await h.promises.mkdir(n,{recursive:!0});let r=50*1024*1024,a=200*1024*1024,o=1e3,i=5;if((await h.promises.stat(t)).size>r)return await h.promises.unlink(t),s.status(400).json({error:"Compressed file too large (max 50MB)"});let c=st("unzip",["-l",t]),u="";c.stdout.on("data",S=>{u+=S.toString()}),await new Promise((S,T)=>{c.on("close",b=>{b!==0?T(new Error("Failed to list zip contents")):S()}),c.on("error",T)});let d=u.split(`
|
|
104
|
+
`),f=0,g=0,m=0;for(let S of d){let T=S.trim().match(/^\s*(\d+)\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.+)$/);if(T){let b=parseInt(T[1]),x=T[2];f+=b,g++;let F=(x.match(/\//g)||[]).length;m=Math.max(m,F)}}if(f>a)return await h.promises.unlink(t),s.status(400).json({error:`Uncompressed size too large (${Math.round(f/1024/1024)}MB > ${a/1024/1024}MB)`});if(g>o)return await h.promises.unlink(t),s.status(400).json({error:`Too many files in archive (${g} > ${o})`});if(m>i)return await h.promises.unlink(t),s.status(400).json({error:`Directory nesting too deep (${m} > ${i})`});let y=st("unzip",["-q",t,"-d",n]);Ts.register(y,{name:"unzip-import"}),y.on("close",async S=>{let T;try{if(await h.promises.unlink(t),S!==0)return await h.promises.rm(n,{recursive:!0,force:!0}),s.status(500).json({error:"Failed to extract zip file"});let b=await h.promises.readdir(n);if(b.length===0)return await h.promises.rm(n,{recursive:!0,force:!0}),s.status(400).json({error:"Empty zip file"});if(T=b[0],!Y(T))return await h.promises.rm(n,{recursive:!0,force:!0}),s.status(400).json({error:"Invalid session directory name in zip file"});let x=I.join(n,T),F=I.join(this.SESSION_DIR,T),me=I.join(x,"events.jsonl");try{await h.promises.access(me)}catch{return await h.promises.rm(n,{recursive:!0,force:!0}),s.status(400).json({error:"Invalid session structure (no events.jsonl)"})}if(h.existsSync(F))return await h.promises.rm(n,{recursive:!0,force:!0}),s.status(409).json({error:"Session already exists"});await h.promises.rename(x,F),await h.promises.rm(n,{recursive:!0,force:!0});let fe=await h.promises.stat(t).catch(()=>({size:0}));Is("SessionImported",{format:"copilot",fileSize:fe.size.toString()}),s.json({success:!0,sessionId:T})}catch(b){console.error("Error importing session:",b),nt(b,{operation:"importSession",sessionId:T||"unknown"}),await h.promises.rm(n,{recursive:!0,force:!0}).catch(()=>{}),s.status(500).json({error:"Error importing session"})}}),y.on("error",async S=>{console.error("Error extracting zip:",S),nt(S,{operation:"importSession_unzip"}),await h.promises.unlink(t).catch(()=>{}),await h.promises.rm(n,{recursive:!0,force:!0}).catch(()=>{}),s.status(500).json({error:"Failed to extract zip file"})})}catch(t){console.error("Error processing upload:",t),nt(t,{operation:"importSession_upload"}),e.file&&await h.promises.unlink(e.file.path).catch(()=>{}),s.status(500).json({error:"Error processing upload"})}}getUploadMiddleware(){return this.upload.single("zipFile")}async _detectFormat(e){try{let s=await h.promises.readdir(e);if(s.length===0)return null;let t=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z_([a-zA-Z0-9_-]+)\.jsonl$/;for(let r of s){let a=r.match(t);if(a)return{format:"pi-mono",sessionId:a[1],fileName:r,extractDir:e}}for(let r of s){let a=I.join(e,r);if((await h.promises.stat(a)).isDirectory()){let i=I.join(a,"events.jsonl");if(h.existsSync(i))return{format:"copilot",sessionId:r,directoryName:r,extractDir:e}}}let n=/^([a-zA-Z0-9_-]+)\.jsonl$/;for(let r of s){let a=I.join(e,r);if((await h.promises.stat(a)).isFile()){let i=r.match(n);if(i){let l=i[1],c=I.join(e,l),u=h.existsSync(c);return{format:"claude",sessionId:l,fileName:r,hasDirectory:u,directoryName:u?l:void 0,extractDir:e}}}}return null}catch(s){return console.error("Error detecting format:",s),null}}async _importCopilotSession(e,s){try{let{sessionId:t,directoryName:n}=e;if(!Y(t))return{success:!1,error:"Invalid session ID",statusCode:400};let r=I.join(s,n),a=I.join(this.SESSION_DIRS.copilot,t),o=I.join(r,"events.jsonl");return h.existsSync(o)?h.existsSync(a)?{success:!1,error:"Session already exists",statusCode:409}:(await h.promises.rename(r,a),await h.promises.writeFile(I.join(a,".imported"),""),{success:!0,sessionId:t,format:"copilot"}):{success:!1,error:"Invalid session structure (no events.jsonl)",statusCode:400}}catch(t){return console.error("Error importing Copilot session:",t),{success:!1,error:`Error importing Copilot session: ${t.message}`,statusCode:500}}}async _importClaudeSession(e,s,t){try{let{sessionId:n,fileName:r,hasDirectory:a,directoryName:o}=e;if(!Y(n))return{success:!1,error:"Invalid session ID",statusCode:400};let i=t.query.project||"imported-sessions",l=I.join(this.SESSION_DIRS.claude,i);await h.promises.mkdir(l,{recursive:!0});let c=I.join(s,r),u=I.join(l,r);if(await h.promises.rename(c,u),a&&o){let d=I.join(s,o),f=I.join(l,o);await h.promises.rename(d,f)}return{success:!0,sessionId:n,format:"claude",project:i}}catch(n){return console.error("Error importing Claude session:",n),{success:!1,error:`Error importing Claude session: ${n.message}`,statusCode:500}}}async _importPiMonoSession(e,s,t){try{let{sessionId:n,fileName:r}=e;if(!Y(n))return{success:!1,error:"Invalid session ID",statusCode:400};let a=t.query.project||"imported-sessions",o=I.join(this.SESSION_DIRS["pi-mono"],a);await h.promises.mkdir(o,{recursive:!0});let i=I.join(s,r),l=I.join(o,r);return await h.promises.rename(i,l),{success:!0,sessionId:n,format:"pi-mono",project:a}}catch(n){return console.error("Error importing Pi-Mono session:",n),{success:!1,error:`Error importing Pi-Mono session: ${n.message}`,statusCode:500}}}async _importByFormat(e,s,t){if(!Y(e.sessionId))return{success:!1,error:"Invalid session ID",statusCode:400};switch(e.format){case"copilot":return await this._importCopilotSession(e,s);case"claude":return await this._importClaudeSession(e,s,t);case"pi-mono":return await this._importPiMonoSession(e,s,t);default:return{success:!1,error:`Unsupported format: ${e.format}`,statusCode:400}}}async _findSessionLocation(e,s=null){try{let t=s?[s,...Object.keys(this.SESSION_DIRS).filter(n=>n!==s)]:Object.keys(this.SESSION_DIRS);for(let n of t){let r=this.SESSION_DIRS[n];if(n==="copilot"){let a=I.join(r,e);if(h.existsSync(a)){let o=I.join(a,"events.jsonl");if(h.existsSync(o))return{source:"copilot",sessionId:e,sessionPath:a,baseDir:r}}}else if(n==="claude"){if(h.existsSync(r)){let a=await h.promises.readdir(r);for(let o of a){let i=I.join(r,o);if((await h.promises.stat(i)).isDirectory()){let c=I.join(i,`${e}.jsonl`);if(h.existsSync(c))return{source:"claude",sessionId:e,sessionFile:c,projectPath:i,project:o,baseDir:r}}}}}else if(n==="pi-mono"&&h.existsSync(r)){let a=await h.promises.readdir(r);for(let o of a){let i=I.join(r,o);if((await h.promises.stat(i)).isDirectory()){let c=await h.promises.readdir(i),u=new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-\\d{3}Z_${e}\\.jsonl$`);for(let d of c)if(u.test(d))return{source:"pi-mono",sessionId:e,fileName:d,sessionFile:I.join(i,d),projectPath:i,project:o,baseDir:r}}}}}return null}catch(t){return console.error("Error finding session location:",t),null}}};Es.exports=rt});var xs=w((ta,vs)=>{var or=Ge(),ir=Ve(),{isValidSessionId:Cs}=z(),{trackEvent:lr}=U(),at=class{constructor(e=null,s=null){this.tagService=e||new or,this.sessionRepository=s||new ir}async getAllTags(e,s){try{let t=await this.tagService.getAllKnownTags();s.json({tags:t})}catch(t){console.error("Error getting all tags:",t),s.status(500).json({error:"Error loading tags"})}}async getSessionTags(e,s){try{let t=e.params.id;if(!Cs(t))return s.status(400).json({error:"Invalid session ID"});let n=await this.sessionRepository.findById(t);if(!n)return s.status(404).json({error:"Session not found"});let r=await this.tagService.getSessionTags(n);s.json({tags:r})}catch(t){console.error("Error getting session tags:",t),s.status(500).json({error:"Error loading session tags"})}}async setSessionTags(e,s){try{let t=e.params.id,{tags:n}=e.body;if(!Cs(t))return s.status(400).json({error:"Invalid session ID"});if(!Array.isArray(n))return s.status(400).json({error:"Tags must be an array"});if(n.length>10)return s.status(400).json({error:"Maximum 10 tags per session"});for(let o of n){if(typeof o!="string"||o.trim().length===0)return s.status(400).json({error:"Tags must be non-empty strings"});if(o.length>30)return s.status(400).json({error:"Tag length must not exceed 30 characters"})}let r=await this.sessionRepository.findById(t);if(!r)return s.status(404).json({error:"Session not found"});let a=await this.tagService.setSessionTags(r,n);lr("TagUpdated",{sessionId:t,tagCount:a.length.toString()}),s.json({tags:a})}catch(t){if(console.error("Error setting session tags:",t),t.message==="Maximum 10 tags per session")return s.status(400).json({error:t.message});if(t.message==="Session must have a directory field")return s.status(400).json({error:"Session does not support tagging"});s.status(500).json({error:"Error saving session tags"})}}};vs.exports=at});var ks=w((sa,Ds)=>{var pe=require("express"),js=require("path"),As=require("compression"),cr=require("helmet"),ur=L(),{requestTimeout:dr,developmentCors:pr,errorHandler:mr,notFoundHandler:fr,telemetryLocals:gr}=gt(),hr=ms(),yr=_s(),Sr=bs(),wr=xs();function _r(p={}){let e=pe();e.set("etag",!1);let s=new hr(p.sessionService),t=new yr(p.insightService,p.sessionService),n=new Sr,r=new wr(p.tagService);return e.use((a,o,i)=>{o.setHeader("Content-Security-Policy","default-src 'self'; style-src 'self' 'unsafe-inline' https: http:; font-src 'self' https: http:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: http:; img-src 'self' data: https: http:; connect-src 'self' https: http:"),i()}),e.use(cr({contentSecurityPolicy:!1,hsts:!1,referrerPolicy:!1,crossOriginEmbedderPolicy:!1,crossOriginOpenerPolicy:!1,crossOriginResourcePolicy:!1})),e.use(As({level:1,threshold:1024,filter:(a,o)=>a.path.includes("/events")&&o.getHeader("Content-Type")?.includes("application/json")?!1:As.filter(a,o)})),e.use(pe.json({limit:"1mb"})),e.use(pe.urlencoded({extended:!0})),e.use(dr),e.use(gr),ur.NODE_ENV==="development"&&e.use(pr),e.use("/public",pe.static(js.join(__dirname,"../public"))),e.set("view engine","ejs"),e.set("views",js.join(__dirname,"../views")),e.get("/",s.getHomepage.bind(s)),e.get("/session/:id",s.getSessionDetail.bind(s)),e.get("/session/:id/time-analyze",s.getTimeAnalysis.bind(s)),e.get("/session/:id/export",s.exportSession.bind(s)),e.get("/api/sessions/load-more",s.loadMoreSessions.bind(s)),e.get("/api/sessions",s.getSessions.bind(s)),e.get("/api/sessions/:id/events",s.getSessionEvents.bind(s)),e.get("/api/sessions/:id/timeline",s.getTimeline.bind(s)),e.get("/api/tags",r.getAllTags.bind(r)),e.get("/api/sessions/:id/tags",r.getSessionTags.bind(r)),e.put("/api/sessions/:id/tags",r.setSessionTags.bind(r)),e.get("/session/:id/share",n.shareSession.bind(n)),e.post("/session/import",(a,o,i)=>n.getUploadMiddleware()(a,o,i),n.importSession.bind(n)),e.post("/session/:id/insight",t.generateInsight.bind(t)),e.get("/session/:id/insight",t.getInsightStatus.bind(t)),e.delete("/session/:id/insight",t.deleteInsight.bind(t)),e.use(fr),e.use(mr),e}Ds.exports=_r});U();var Ir=ks(),ot=L(),Tr=de(),Ms=Ir();module.exports=Ms;if(require.main===module){let p=Ms.listen(ot.PORT,()=>{console.log(`\u{1F680} Copilot Session Viewer running at http://localhost:${ot.PORT}`),console.log(`\u{1F527} Environment: ${ot.NODE_ENV}`),console.log(`\u26A1 Active processes: ${Tr.getActiveCount()}`)});process.on("SIGTERM",()=>{console.log("\u{1F4DB} SIGTERM received, closing server..."),p.close(()=>{console.log("\u2705 Server closed")})})}
|