MCPcopy Index your code
hub / github.com/codeaashu/claude-code / generateUsageReport

Function generateUsageReport

src/commands/insights.ts:2796–3023  ·  view source on GitHub ↗
(options?: {
  collectRemote?: boolean
})

Source from the content-addressed store, hash-verified

2794// ============================================================================
2795
2796export async function generateUsageReport(options?: {
2797 collectRemote?: boolean
2798}): Promise<{
2799 insights: InsightResults
2800 htmlPath: string
2801 data: AggregatedData
2802 remoteStats?: { hosts: RemoteHostInfo[]; totalCopied: number }
2803 facets: Map<string, SessionFacets>
2804}> {
2805 let remoteStats: { hosts: RemoteHostInfo[]; totalCopied: number } | undefined
2806
2807 // Optionally collect data from remote hosts first (ant-only)
2808 if (process.env.USER_TYPE === 'ant' && options?.collectRemote) {
2809 const destDir = join(getClaudeConfigHomeDir(), 'projects')
2810 const { hosts, totalCopied } = await collectAllRemoteHostData(destDir)
2811 remoteStats = { hosts, totalCopied }
2812 }
2813
2814 // Phase 1: Lite scan — filesystem metadata only (no JSONL parsing)
2815 const allScannedSessions = await scanAllSessions()
2816 const totalSessionsScanned = allScannedSessions.length
2817
2818 // Phase 2: Load SessionMeta — use cache where available, parse only uncached
2819 // Read cached metas in parallel batches to avoid blocking the event loop
2820 const META_BATCH_SIZE = 50
2821 const MAX_SESSIONS_TO_LOAD = 200
2822 let allMetas: SessionMeta[] = []
2823 const uncachedSessions: LiteSessionInfo[] = []
2824
2825 for (let i = 0; i < allScannedSessions.length; i += META_BATCH_SIZE) {
2826 const batch = allScannedSessions.slice(i, i + META_BATCH_SIZE)
2827 const results = await Promise.all(
2828 batch.map(async sessionInfo => ({
2829 sessionInfo,
2830 cached: await loadCachedSessionMeta(sessionInfo.sessionId),
2831 })),
2832 )
2833 for (const { sessionInfo, cached } of results) {
2834 if (cached) {
2835 allMetas.push(cached)
2836 } else if (uncachedSessions.length < MAX_SESSIONS_TO_LOAD) {
2837 uncachedSessions.push(sessionInfo)
2838 }
2839 }
2840 }
2841
2842 // Load full message data only for uncached sessions and compute SessionMeta
2843 const logsForFacets = new Map<string, LogOption>()
2844
2845 // Filter out /insights meta-sessions (facet extraction API calls get logged as sessions)
2846 const isMetaSession = (log: LogOption): boolean => {
2847 for (const msg of log.messages.slice(0, 5)) {
2848 if (msg.type === 'user' && msg.message) {
2849 const content = msg.message.content
2850 if (typeof content === 'string') {
2851 if (
2852 content.includes('RESPOND WITH ONLY A VALID JSON OBJECT') ||
2853 content.includes('record_facets')

Callers 1

getPromptForCommandFunction · 0.85

Calls 15

scanAllSessionsFunction · 0.85
loadCachedSessionMetaFunction · 0.85
isMetaSessionFunction · 0.85
hasValidDatesFunction · 0.85
logToSessionMetaFunction · 0.85
saveSessionMetaFunction · 0.85
loadCachedFacetsFunction · 0.85
extractFacetsFromAPIFunction · 0.85
saveFacetsFunction · 0.85
isMinimalSessionFunction · 0.85
aggregateDataFunction · 0.85

Tested by

no test coverage detected