sidekick-agent-hub 0.28.0 → 0.28.1
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/sidekick-main.mjs +4 -4
- package/package.json +1 -1
package/dist/sidekick-main.mjs
CHANGED
|
@@ -1061,7 +1061,7 @@ Examples:
|
|
|
1061
1061
|
$ sidekick accounts doctor Read-only credential, expiry, and running-app inspection
|
|
1062
1062
|
`});var MIe={};hn(MIe,{REDIRECT_UNSUPPORTED_COMMANDS:()=>HJe,installOutputRedirect:()=>jJe});import*as ox from"fs";function jJe(e,t=process.env){let n=ox.openSync(e,"w");t.FORCE_COLOR||(F.level=0);let r=process.stdout;r.write=((o,i,s)=>{let c=typeof i=="function"?i:s,l=typeof o=="string"?Buffer.from(o,typeof i=="string"?i:"utf8"):o;return ox.writeSync(n,l),typeof c=="function"&&c(),!0}),process.on("exit",()=>{try{ox.closeSync(n)}catch{}})}var HJe,QIe=B(()=>{"use strict";_i();HJe=new Set(["dashboard","mcp"])});var OIe=B(()=>{"use strict";Pt()});import*as PIe from"fs";function JV(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:String(e)}var GJe,NIe,sF,zIe=B(()=>{"use strict";Pt();Pt();Pt();OIe();GJe={"claude-code":"Claude Code",opencode:"OpenCode",codex:"Codex CLI"},NIe=200,sF=class e{_aggregator=new Ec({readPlanFile:t=>{try{return PIe.readFileSync(t,"utf-8")}catch{return null}}});_timeline=[];_fileMap=new Map;_urlMap=new Map;_dirMap=new Map;_cmdMap=new Map;_todos=[];_todoSeen=new Set;_providerName;_quota=null;_billingBlock=null;_subagentStats=[];_providerStatus=null;_openaiStatus=null;_updateInfo=null;_sessionId;_checkpointProviderId;_version=0;_metricsCache=null;_lastKnownCompactionCount=0;_timelineAppendCount=0;_taskToolCallCounts=new Map;static TASK_MGMT_TOOLS=["TaskCreate","TaskUpdate","TaskGet","TaskList"];get version(){return this._version}touch(){this._version++}reset(){this.resetSessionEvents(),this._providerName=void 0,this._quota=null,this._providerStatus=null,this._openaiStatus=null,this._updateInfo=null,this._sessionId=void 0}resetSessionEvents(){this.touch(),this._aggregator.reset(),this._timeline=[],this._timelineAppendCount=0,this._fileMap.clear(),this._urlMap.clear(),this._dirMap.clear(),this._cmdMap.clear(),this._todos=[],this._todoSeen.clear(),this._checkpointProviderId=void 0,this._lastKnownCompactionCount=0,this._taskToolCallCounts.clear(),this._subagentStats=[]}setSessionId(t){this.touch(),t!==this._sessionId&&(this._checkpointProviderId=void 0),this._sessionId=t}markHistoryReplayed(t){this._checkpointProviderId=this._sessionId&&t!=="opencode"?t:void 0}tryRestoreFromSnapshot(t,n,r){if(this.touch(),this._checkpointProviderId=void 0,n==="opencode")return null;let o=Vq(t);if(!o)return null;if(o.providerId!==n||o.consumer?.checkpointRevision!==3||o.consumer.consumerType!=="cli")return q0(t),null;if(!Jq(o,r))return q0(t),null;if(!this._aggregator.restore(o.aggregator))return q0(t),null;let i=o.consumer;if(Array.isArray(i.timeline)){this._timeline=i.timeline,this._timelineAppendCount=this._timeline.length;for(let s of this._timeline){s.type==="tool_call"&&(s.type="tool_use"),s.type==="assistant_response"&&(s.type="assistant");let c=s;if(!s.summary&&typeof c.description=="string"&&(s.summary=c.description),!s.toolName&&c.metadata){let l=c.metadata;typeof l.toolName=="string"&&(s.toolName=l.toolName)}if(!s.summary)if(s.toolName)s.summary=s.toolInput?`${s.toolName} ${s.toolInput}`:s.toolName;else{let l={user:"(user message)",assistant:"(assistant)",tool_result:"(tool result)",summary:"Context compacted",system:"(system)"};s.summary=l[s.type]||s.type}}}return Array.isArray(i.fileMap)&&(this._fileMap=new Map(i.fileMap)),Array.isArray(i.urlMap)&&(this._urlMap=new Map(i.urlMap)),Array.isArray(i.dirMap)&&(this._dirMap=new Map(i.dirMap)),Array.isArray(i.cmdMap)&&(this._cmdMap=new Map(i.cmdMap)),Array.isArray(i.todos)&&(this._todos=i.todos,this._todoSeen=new Set(this._todos)),typeof i.providerName=="string"&&(this._providerName=i.providerName),typeof i.lastKnownCompactionCount=="number"&&(this._lastKnownCompactionCount=i.lastKnownCompactionCount),Array.isArray(i.taskToolCallCounts)&&(this._taskToolCallCounts=new Map(i.taskToolCallCounts)),this._sessionId=t,this._checkpointProviderId=n,o.readerPosition}persistSnapshot(t,n){if(!this._sessionId||!this._checkpointProviderId)return;let r=this._aggregator.serialize(),o={version:r.version,sessionId:this._sessionId,providerId:this._checkpointProviderId,readerPosition:t,sourceSize:n,createdAt:new Date().toISOString(),aggregator:r,consumer:{consumerType:"cli",checkpointRevision:3,timeline:this._timeline,fileMap:Array.from(this._fileMap.entries()),urlMap:Array.from(this._urlMap.entries()),dirMap:Array.from(this._dirMap.entries()),cmdMap:Array.from(this._cmdMap.entries()),todos:this._todos,providerName:this._providerName,lastKnownCompactionCount:this._lastKnownCompactionCount,taskToolCallCounts:Array.from(this._taskToolCallCounts.entries())}};Yq(o)}processEvent(t){if(this.touch(),this._aggregator.processFollowEvent(t),!this._providerName&&t.providerId&&(this._providerName=GJe[t.providerId]||t.providerId),t.rateLimits&&this.extractCodexQuota(t),t.type==="tool_use"&&t.toolName&&!e.TASK_MGMT_TOOLS.includes(t.toolName)){let r=this._aggregator.getTaskState();for(let[o,i]of r.tasks)i.status==="in_progress"&&this._taskToolCallCounts.set(o,(this._taskToolCallCounts.get(o)||0)+1)}this.extractFileTouch(t),this.extractUrl(t),this.extractDirectory(t),this.extractCommand(t),this.extractTodo(t);let n=this._aggregator.getCompactionEvents().length;if(n>this._lastKnownCompactionCount){for(let r=this._lastKnownCompactionCount;r<n;r++){let o=this._aggregator.getCompactionEvents()[r],i=o.timestamp instanceof Date?o.timestamp.toISOString():String(o.timestamp);this._timeline.push({providerId:"claude-code",type:"summary",timestamp:i,summary:o.contextBefore>0&&o.contextAfter>0?`Context compacted: ${JV(o.contextBefore)} \u2192 ${JV(o.contextAfter)} (${JV(o.tokensReclaimed)} reclaimed)`:"Context compacted"}),this._timelineAppendCount++,this._timeline.length>NIe&&this._timeline.shift()}this._lastKnownCompactionCount=n}this._timeline.push(t),this._timelineAppendCount++,this._timeline.length>NIe&&this._timeline.shift()}setQuota(t){this.touch(),this._quota=t}setSubagentStats(t){this.touch(),this._subagentStats=t}setBillingBlock(t){this.touch(),this._billingBlock=t}setProviderStatus(t){this.touch(),this._providerStatus=t}setOpenAIStatus(t){this.touch(),this._openaiStatus=t}setUpdateInfo(t){this.touch(),this._updateInfo=t}getMetrics(){if(this._metricsCache&&this._metricsCache.version===this._version)return this._metricsCache.metrics;let t=this.buildMetrics();return this._metricsCache={version:this._version,metrics:t},t}buildMetrics(){let t=this._aggregator.getMetrics(),n=t.subagents.map(p=>({id:p.id,description:p.description,subagentType:p.subagentType,spawnTime:p.spawnTime,completionTime:p.completionTime,status:p.status,durationMs:p.durationMs,isParallel:!1}));this.detectParallelSubagents(n);let r=t.toolStats.map(p=>({name:p.name,calls:p.successCount+p.failureCount+p.pendingCount,pending:p.pendingCount,lastCallTime:void 0})),o=t.modelStats.map(p=>({model:p.model,calls:p.calls,tokens:p.tokens,cost:p.cost,priced:p.priced})),i=new Map;for(let p of t.taskState.tasks.values())i.set(p.taskId,{taskId:p.taskId,subject:p.subject,status:p.status,blockedBy:p.blockedBy,blocks:p.blocks,subagentType:p.subagentType,isGoalGate:p.isGoalGate,toolCallCount:this._taskToolCallCounts.get(p.taskId)||0,activeForm:p.activeForm});for(let p of t.subagents)i.has(p.id)||i.set(p.id,{taskId:p.id,subject:p.description||`${p.subagentType} agent`,status:p.status==="completed"?"completed":"in_progress",blockedBy:[],blocks:[],subagentType:p.subagentType,toolCallCount:0,activeForm:p.status==="running"?`Running ${p.subagentType}`:void 0});if(t.plan)for(let p of t.plan.steps){let h=`plan-${p.id}`;if(!i.has(h)){let g=p.status==="completed"?"completed":p.status==="in_progress"?"in_progress":"pending";i.set(h,{taskId:h,subject:p.description,status:g,blockedBy:[],blocks:[],toolCallCount:0,activeForm:p.status==="in_progress"?`Working on ${p.description}`:void 0})}}let s=Array.from(i.values()),c=t.compactionEvents.map(p=>({timestamp:p.timestamp instanceof Date?p.timestamp.toISOString():String(p.timestamp),contextBefore:p.contextBefore,contextAfter:p.contextAfter,tokensReclaimed:p.tokensReclaimed,source:p.source})),l=this.convertPlan(t.plan);return{tokens:{input:t.tokens.inputTokens,output:t.tokens.outputTokens,cacheRead:t.tokens.cacheReadTokens,cacheWrite:t.tokens.cacheWriteTokens,reasoning:t.tokens.reasoningTokens,total:Ei(t.tokens).total,cost:t.tokens.costUsd},sessionTokens:C0(t.tokens,this._subagentStats),context:this.computeContextGauge(t.currentContextSize,t.currentModel),burnRate:t.burnRate.points,toolStats:r,modelStats:o,timeline:[...this._timeline],timelineAppendCount:this._timelineAppendCount,tasks:s,fileTouches:Array.from(this._fileMap.values()).sort((p,h)=>h.reads+h.writes+h.edits-(p.reads+p.writes+p.edits)),subagents:n,compactionCount:t.compactionCount,compactionEvents:c,quota:this._quota,billingBlock:this._billingBlock,providerStatus:this._providerStatus,openaiStatus:this._openaiStatus,eventCount:t.eventCount,sessionStartTime:t.sessionStartTime??void 0,currentModel:t.currentModel??void 0,providerId:t.providerId??void 0,providerName:this._providerName,urls:Array.from(this._urlMap.values()).sort((p,h)=>h.count-p.count),directories:Array.from(this._dirMap.values()).sort((p,h)=>h.count-p.count),commands:Array.from(this._cmdMap.values()).sort((p,h)=>h.count-p.count),todos:[...this._todos],plan:l,contextAttribution:{...t.contextAttribution},updateInfo:this._updateInfo,sessionId:this._sessionId,permissionMode:t.permissionMode??null,contextTimeline:t.contextTimeline??[],toolFrequency:t.toolFrequency??[],wordFrequency:t.wordFrequency??[],patterns:t.patterns??[],heatmapBuckets:t.heatmapBuckets??[]}}detectParallelSubagents(t){for(let n=0;n<t.length;n++){let r=t[n],o=new Date(r.spawnTime).getTime(),i=r.completionTime?new Date(r.completionTime).getTime():Date.now();if(!isNaN(o))for(let s=n+1;s<t.length;s++){let c=t[s],l=new Date(c.spawnTime).getTime(),p=c.completionTime?new Date(c.completionTime).getTime():Date.now();isNaN(l)||o<p&&l<i&&(r.isParallel=!0,c.isParallel=!0)}}}computeContextGauge(t,n){let r=td(n??void 0),o=t,i=r>0?Math.min(100,Math.round(o/r*100)):0;return{used:o,limit:r,percent:i}}convertPlan(t){return t?{title:t.title??"Plan",steps:t.steps.map(n=>({id:n.id,description:n.description,status:n.status,phase:n.phase,complexity:n.complexity,startedAt:n.startedAt,completedAt:n.completedAt,durationMs:n.durationMs,tokensUsed:n.tokensUsed,toolCalls:n.toolCalls,errorMessage:n.errorMessage,costUsd:n.costUsd})),source:t.source,completionRate:t.completionRate,totalDurationMs:t.totalDurationMs,rawMarkdown:t.rawMarkdown,active:t.active,enteredAt:t.enteredAt?.toISOString(),exitedAt:t.exitedAt?.toISOString()}:null}extractFileTouch(t){if(t.type!=="tool_use"||!t.toolName)return;let n=t.raw;if(!n?.input)return;let r=n.input,o=r.file_path||r.path;if(!o)return;let i=t.toolName;if(!["Read","Write","Edit","Glob","Grep"].includes(i))return;let s=this._fileMap.get(o)||{path:o,reads:0,writes:0,edits:0};i==="Read"||i==="Glob"||i==="Grep"?s.reads++:i==="Write"?s.writes++:i==="Edit"&&s.edits++,this._fileMap.set(o,s)}static URL_TOOLS=["WebFetch","WebSearch"];static SEARCH_TOOLS=["Grep","Glob"];static COMMAND_PATTERN=/^(git|npm|npx|yarn|pnpm|node|python|pip|docker|make|cargo|go|rustc|tsc|eslint|prettier|vitest|jest|pytest)/i;static TODO_PATTERN=/TODO:?\s*(.+?)(?:\n|$)/gi;extractUrl(t){if(t.type!=="tool_use"||!t.toolName||!e.URL_TOOLS.includes(t.toolName))return;let n=t.raw;if(!n?.input)return;let r=n.input,o=r.url||r.query;if(!o)return;let i=this._urlMap.get(o)||{url:o,count:0};i.count++,this._urlMap.set(o,i)}extractDirectory(t){if(t.type!=="tool_use"||!t.toolName||!e.SEARCH_TOOLS.includes(t.toolName))return;let n=t.raw;if(!n?.input)return;let r=n.input,o=r.path;if(!o)return;let i=this._dirMap.get(o)||{path:o,count:0,patterns:[]};i.count++;let s=r.pattern;s&&!i.patterns.includes(s)&&i.patterns.push(s),this._dirMap.set(o,i)}extractCommand(t){if(t.type!=="tool_use"||t.toolName!=="Bash")return;let n=t.raw;if(!n?.input)return;let o=n.input.command;if(!o)return;let i=o.match(e.COMMAND_PATTERN);if(!i)return;let s=i[1].toLowerCase(),c=this._cmdMap.get(s)||{name:s,count:0,examples:[]};c.count++;let l=o.split(`
|
|
1063
1063
|
`)[0].substring(0,60);!c.examples.includes(l)&&c.examples.length<5&&c.examples.push(l),this._cmdMap.set(s,c)}extractTodo(t){let n=this.extractFullTextFromEvent(t)||t.summary;if(!n)return;let r=n.matchAll(e.TODO_PATTERN);for(let o of r){let i=o[1].trim();i&&!this._todoSeen.has(i.toLowerCase())&&(this._todos.push(i),this._todoSeen.add(i.toLowerCase()))}}extractFullTextFromEvent(t){let o=t.raw?.message?.content;if(Array.isArray(o)){let i=[];for(let s of o){let c=s;c.type==="text"&&typeof c.text=="string"&&i.push(c.text)}if(i.length>0)return i.join(`
|
|
1064
|
-
`)}return null}extractCodexQuota(t){let n=t.rateLimits;!n?.primary&&!n?.secondary||(this._quota=rB({primary:n.primary?{used_percent:n.primary.usedPercent,window_minutes:n.primary.windowMinutes,resets_at:n.primary.resetsAt}:void 0,secondary:n.secondary?{used_percent:n.secondary.usedPercent,window_minutes:n.secondary.windowMinutes,resets_at:n.secondary.resetsAt}:void 0})??this._quota)}}});async function FIe(e){let t=xr(e),n=await Sf().catch(()=>null),[r,o,i]=await Promise.all([hh(t,{status:"all"}).catch(()=>[]),gh(t).catch(()=>[]),Ah(t).catch(()=>[])]),s=[];for(let p of t.candidates)if(s=await AT(p).catch(()=>[]),s.length>0)break;s.length===0&&(s=await W9(e).catch(()=>[]));let c=qJe(n),l=ZJe(n);return{sessions:c,tasks:r,decisions:o,notes:i,plans:s,totalTokens:l.tokens,totalCost:l.cost,totalSessions:l.sessions}}function qJe(e){if(!e?.daily)return[];let t=[],n=Object.values(e.daily);n.sort((r,o)=>o.date.localeCompare(r.date));for(let r of n)t.push({date:r.date,sessionCount:r.sessionCount,inputTokens:r.tokens.inputTokens,outputTokens:r.tokens.outputTokens,cacheWriteTokens:r.tokens.cacheWriteTokens,cacheReadTokens:r.tokens.cacheReadTokens,totalTokens:Ei(r.tokens).total,totalCost:r.totalCost,messageCount:r.messageCount,modelUsage:r.modelUsage.map(o=>({model:o.model,calls:o.calls})),toolUsage:r.toolUsage.map(o=>({tool:o.tool,calls:o.calls}))});return t}function ZJe(e){if(!e?.allTime)return{tokens:0,cost:0,sessions:0};let t=e.allTime;return{tokens:Ei(t.tokens).total,cost:t.totalCost,sessions:t.sessionCount}}var UIe=B(()=>{"use strict";Pt()});var LIe,KJe,aF,jIe=B(()=>{"use strict";Pt();LIe=3e5,KJe="No OAuth token available",aF=class{_poller;_callback=null;constructor(){this._poller=new nB({activeIntervalMs:LIe,idleIntervalMs:LIe,getAccessToken:async()=>{let t=await UT();if(!t)throw new Error(KJe);return t.accessToken}}),this._poller.onUpdate(t=>{this._callback?.(t)})}onUpdate(t){this._callback=t}start(){this._poller.start()}stop(){this._poller.stop()}getCached(){return this._poller.getLatest()}async fetchOnce(){return Qf({providerId:"claude-code"})}}});var YJe,cF,HIe=B(()=>{"use strict";Pt();YJe=6e4,cF=class{constructor(t="claude-code"){this.providerId=t}providerId;_interval=null;_controller=null;_cached=null;_cachedOpenAI=null;_callback=null;_openAICallback=null;onUpdate(t){this._callback=t}onOpenAIUpdate(t){this._openAICallback=t}get pollsAnything(){return this.providerId!=="opencode"}start(){this._interval||!this.pollsAnything||(this._fetchAll(),this._interval=setInterval(()=>{this._fetchAll()},YJe))}stop(){this._interval&&clearInterval(this._interval),this._interval=null,this._controller?.abort(),this._controller=null}getCached(){return this._cached}getCachedOpenAI(){return this._cachedOpenAI}async fetchOnce(){return this.providerId==="opencode"?null:Kp(this.providerId)}async _fetchAll(){if(this._controller||this.providerId==="opencode")return;let t=new AbortController;this._controller=t;try{let n=await Kp(this.providerId,{signal:t.signal});if(t.signal.aborted||this._controller!==t)return;this.providerId==="claude-code"?(this._cached=n,this._callback?.(n)):(this._cachedOpenAI=n,this._openAICallback?.(n))}finally{this._controller===t&&(this._controller=null)}}}});function GIe(e,t,n){return e==="claude-code"?{providerStatus:t,openaiStatus:null}:e==="codex"?{providerStatus:null,openaiStatus:n}:{providerStatus:null,openaiStatus:null}}var qIe=B(()=>{"use strict"});import*as Hh from"fs";import*as WV from"path";function WJe(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number);for(let o=0;o<3;o++){let i=n[o]||0,s=r[o]||0;if(i>s)return!0;if(i<s)return!1}return!1}var VJe,ZIe,JJe,uF,KIe=B(()=>{"use strict";Pt();VJe="https://registry.npmjs.org/sidekick-agent-hub/latest",ZIe="update-check.json",JJe=14400*1e3,uF=class{_callback=null;onResult(t){this._callback=t}async check(){try{let t="0.28.
|
|
1064
|
+
`)}return null}extractCodexQuota(t){let n=t.rateLimits;!n?.primary&&!n?.secondary||(this._quota=rB({primary:n.primary?{used_percent:n.primary.usedPercent,window_minutes:n.primary.windowMinutes,resets_at:n.primary.resetsAt}:void 0,secondary:n.secondary?{used_percent:n.secondary.usedPercent,window_minutes:n.secondary.windowMinutes,resets_at:n.secondary.resetsAt}:void 0})??this._quota)}}});async function FIe(e){let t=xr(e),n=await Sf().catch(()=>null),[r,o,i]=await Promise.all([hh(t,{status:"all"}).catch(()=>[]),gh(t).catch(()=>[]),Ah(t).catch(()=>[])]),s=[];for(let p of t.candidates)if(s=await AT(p).catch(()=>[]),s.length>0)break;s.length===0&&(s=await W9(e).catch(()=>[]));let c=qJe(n),l=ZJe(n);return{sessions:c,tasks:r,decisions:o,notes:i,plans:s,totalTokens:l.tokens,totalCost:l.cost,totalSessions:l.sessions}}function qJe(e){if(!e?.daily)return[];let t=[],n=Object.values(e.daily);n.sort((r,o)=>o.date.localeCompare(r.date));for(let r of n)t.push({date:r.date,sessionCount:r.sessionCount,inputTokens:r.tokens.inputTokens,outputTokens:r.tokens.outputTokens,cacheWriteTokens:r.tokens.cacheWriteTokens,cacheReadTokens:r.tokens.cacheReadTokens,totalTokens:Ei(r.tokens).total,totalCost:r.totalCost,messageCount:r.messageCount,modelUsage:r.modelUsage.map(o=>({model:o.model,calls:o.calls})),toolUsage:r.toolUsage.map(o=>({tool:o.tool,calls:o.calls}))});return t}function ZJe(e){if(!e?.allTime)return{tokens:0,cost:0,sessions:0};let t=e.allTime;return{tokens:Ei(t.tokens).total,cost:t.totalCost,sessions:t.sessionCount}}var UIe=B(()=>{"use strict";Pt()});var LIe,KJe,aF,jIe=B(()=>{"use strict";Pt();LIe=3e5,KJe="No OAuth token available",aF=class{_poller;_callback=null;constructor(){this._poller=new nB({activeIntervalMs:LIe,idleIntervalMs:LIe,getAccessToken:async()=>{let t=await UT();if(!t)throw new Error(KJe);return t.accessToken}}),this._poller.onUpdate(t=>{this._callback?.(t)})}onUpdate(t){this._callback=t}start(){this._poller.start()}stop(){this._poller.stop()}getCached(){return this._poller.getLatest()}async fetchOnce(){return Qf({providerId:"claude-code"})}}});var YJe,cF,HIe=B(()=>{"use strict";Pt();YJe=6e4,cF=class{constructor(t="claude-code"){this.providerId=t}providerId;_interval=null;_controller=null;_cached=null;_cachedOpenAI=null;_callback=null;_openAICallback=null;onUpdate(t){this._callback=t}onOpenAIUpdate(t){this._openAICallback=t}get pollsAnything(){return this.providerId!=="opencode"}start(){this._interval||!this.pollsAnything||(this._fetchAll(),this._interval=setInterval(()=>{this._fetchAll()},YJe))}stop(){this._interval&&clearInterval(this._interval),this._interval=null,this._controller?.abort(),this._controller=null}getCached(){return this._cached}getCachedOpenAI(){return this._cachedOpenAI}async fetchOnce(){return this.providerId==="opencode"?null:Kp(this.providerId)}async _fetchAll(){if(this._controller||this.providerId==="opencode")return;let t=new AbortController;this._controller=t;try{let n=await Kp(this.providerId,{signal:t.signal});if(t.signal.aborted||this._controller!==t)return;this.providerId==="claude-code"?(this._cached=n,this._callback?.(n)):(this._cachedOpenAI=n,this._openAICallback?.(n))}finally{this._controller===t&&(this._controller=null)}}}});function GIe(e,t,n){return e==="claude-code"?{providerStatus:t,openaiStatus:null}:e==="codex"?{providerStatus:null,openaiStatus:n}:{providerStatus:null,openaiStatus:null}}var qIe=B(()=>{"use strict"});import*as Hh from"fs";import*as WV from"path";function WJe(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number);for(let o=0;o<3;o++){let i=n[o]||0,s=r[o]||0;if(i>s)return!0;if(i<s)return!1}return!1}var VJe,ZIe,JJe,uF,KIe=B(()=>{"use strict";Pt();VJe="https://registry.npmjs.org/sidekick-agent-hub/latest",ZIe="update-check.json",JJe=14400*1e3,uF=class{_callback=null;onResult(t){this._callback=t}async check(){try{let t="0.28.1",n=this.readCache(),r;n&&Date.now()-n.checkedAt<JJe?r=n.latest:(r=await this.fetchLatest(),this.writeCache({latest:r,checkedAt:Date.now()})),WJe(r,t)?this._callback?.({current:t,latest:r}):this._callback?.(null)}catch{this._callback?.(null)}}async fetchLatest(){let t=await fetch(VJe,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(5e3)});if(!t.ok)throw new Error(`Registry returned ${t.status}`);return(await t.json()).version}readCache(){try{let t=WV.join(co(),ZIe);if(!Hh.existsSync(t))return null;let n=Hh.readFileSync(t,"utf8"),r=JSON.parse(n);if(r.latest&&typeof r.checkedAt=="number")return r}catch{}return null}writeCache(t){try{let n=co();Hh.existsSync(n)||Hh.mkdirSync(n,{recursive:!0}),Hh.writeFileSync(WV.join(n,ZIe),JSON.stringify(t),"utf8")}catch{}}}});function YIe(e){let t=e.provider==="codex"?"Codex":"Claude";switch(e.recovery){case"sign_in":return e.diagnosis==="missing_credentials"?`${t} is not signed in. Sign in with the provider CLI before retrying.`:`${t} OAuth sign-in has expired or was rejected. Sign in again before retrying.`;case"update_credentials":return e.diagnosis==="missing_credentials"?`${t} API key is not configured. Set the API key before retrying.`:`${t} API credentials were rejected. Update the API key before retrying.`;case"check_authentication":return`${t} authentication needs attention. Check the credentials used by this request.`;case"start_new_session":return`${t} conversation is invalid or expired. Start a new provider session.`;case"check_connection":return`${t} connection failed. Check the network, proxy, or firewall.`;case"review_execution_policy":return`${t} execution was denied by policy. Review the requested operation and permissions.`;case"repair_runtime":return`${t} runtime is unavailable. Check its installation and executable path.`;case"reduce_context":return`${t} context limit exceeded. Reduce the input or start a new session.`;case"retry_later":return e.diagnosis==="timeout"?`${t} request timed out. Retry when ready.`:e.diagnosis==="rate_limited"||e.diagnosis==="overloaded"?`${t} is rate limited or overloaded. Wait before retrying.`:`${t} service request was unavailable. Retry later.`;default:return`${t} request failed for an unknown reason. Inspect the error details.`}}var VIe=B(()=>{"use strict"});function RC(e){let t=e.provider==="codex"?"OpenAI":"Claude",n=`${t} public service status`;if(e.availability==="unavailable")return{label:n,color:"gray",visible:!0,summary:`${t} status unavailable`,lines:["Status unavailable",`Checked: ${e.checkedAt}`,`Source: ${e.sourceUrl}`]};let r=e.incidents===null,o=new Map(e.components.map(s=>[s.id,s.name])),i=[e.description,`Checked: ${e.checkedAt}`,`Provider updated: ${e.providerUpdatedAt??"not reported"}`];for(let s of e.components.filter(c=>c.status!=="operational"))i.push(`${s.name}: ${s.status.replace(/_/g," ")}`);r&&i.push("Incident information unavailable.");for(let s of e.incidents??[])i.push(`${s.title} (${s.status}, ${s.impact})`),i.push(`Components: ${s.componentIds===null?"not reported":s.componentIds.length===0?"none reported":s.componentIds.map(c=>o.get(c)??`${c} (unmapped)`).join(", ")}`),i.push(`Incident updated: ${s.updatedAt??"not reported"}`),s.url&&i.push(s.url);return i.push("Public vendor information; incidents do not establish the cause of a request failure."),{label:n,lines:i,visible:e.severity!=="none"||r||!!e.incidents?.length,color:e.severity==="none"?r?"gray":"green":["minor","maintenance"].includes(e.severity)?"yellow":"red",summary:`${t} public status: ${r&&e.severity==="none"?"partial evidence":e.severity}`}}var lF=B(()=>{"use strict"});function yl(e){let t=e.replace(/\\/g,"/").split("/");return t.length<=3?e:".../"+t.slice(-3).join("/")}function rr(e){return qi(e,{suffixCase:"upper"})}function Ed(e){return M0(e,{style:"compact",includeMilliseconds:!0,secondsFractionDigits:1})}function XJe(e){return e.replace(/\{[^}]*\}/g,"")}function $C(e){return XJe(e).length}function Ji(e,t){return e.length<=t?e:e.substring(0,t-3)+"..."}function hy(e){try{return new Date(e).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}catch{return"??:??:??"}}function JIe(e){let t=new Date(e).getTime(),n=Date.now()-t;if(isNaN(n)||n<0)return"--:--:--";let r=Math.floor(n/1e3),o=Math.floor(r/3600),i=Math.floor(r%3600/60),s=r%60;return`${String(o).padStart(2,"0")}:${String(i).padStart(2,"0")}:${String(s).padStart(2,"0")}`}function lo(e,t=40){let o=Math.max(0,t-3-e.length-1),i="\u2500".repeat(o);return`{grey-fg}\u2500\u2500 {/grey-fg}{bold}${e}{/bold}{grey-fg} ${i}{/grey-fg}`}function gy(e,t,n="green"){let r=Math.max(0,Math.min(100,e)),o=Math.round(r/100*t),i=t-o;return`{${n}-fg}${"\u2588".repeat(o)}{/${n}-fg}{grey-fg}${"\u2591".repeat(i)}{/grey-fg}`}function s1(e,t=25){let n=e.slice(-t);if(n.length===0)return{spark:"",max:0,latest:0};let r=Math.max(...n,1),o=n[n.length-1],i=[" ","\u2581","\u2582","\u2583","\u2584","\u2585","\u2586","\u2587","\u2588"];return{spark:n.map(c=>i[Math.min(8,Math.round(c/r*8))]).join(""),max:r,latest:o}}function WIe(e,t=60){if(e.length===0)return"{grey-fg}(no activity data){/grey-fg}";let n=Math.max(...e.map(c=>c.count),1),r=[" ","\u2591","\u2592","\u2593","\u2588"],o=e.slice(-t),i=o.map(c=>{let l=Math.min(4,Math.round(c.count/n*4));return r[l]}).join(""),s=[];for(let c=0;c<o.length;c+=5){let l=new Date(o[c].timestamp),p=l.getHours().toString().padStart(2,"0"),h=l.getMinutes().toString().padStart(2,"0");s.push(`${p}:${h}`)}return`{cyan-fg}${i}{/cyan-fg}
|
|
1065
1065
|
{grey-fg}${s.join(" ")}{/grey-fg}`}function XIe(e,t){let n=Math.max(0,Math.min(100,e)),r=Math.round(n/100*t);return"\u2588".repeat(r)+"\u2591".repeat(t-r)}function Zr(){return Math.max(40,(process.stdout.columns||80)-29)}function Qo(e,t,n=""){let r=$C(n);return e.split(`
|
|
1066
1066
|
`).map(o=>{if($C(o)<=t)return o;let i=o.split(" "),s=[],c="",l=0,p=()=>s.length===0;for(let h of i){let g=$C(h);if(l===0)c=h,l=g;else{let v=p()?t:t-r;l+1+g<=v?(c+=" "+h,l+=1+g):(s.push(c),c=h,l=g)}}return c&&s.push(c),s.map((h,g)=>g===0?h:n+h).join(`
|
|
1067
1067
|
`)}).join(`
|
|
@@ -1137,7 +1137,7 @@ ${this.inferenceClient?.getEnableHint()??"Configure inference provider"}{/grey-f
|
|
|
1137
1137
|
`)}renderPatterns(t,n,r){let o=r?.width??Zr(),i=[];i.push(lo("Event Patterns",o)),i.push("");let s=n.patterns;if(!s||s.length===0)return i.push("{grey-fg}(patterns emerge after repeated events){/grey-fg}"),i.join(`
|
|
1138
1138
|
`);let c=s.slice(0,12),l=c[0]?.count??1,p=Math.max(8,Math.floor(o*.3));for(let h of c){let g=h.count/l*100,v=gy(g,p,"magenta"),E=rr(h.count).padStart(5);if(i.push(`${v} ${E} {magenta-fg}${h.template}{/magenta-fg}`),h.examples.length>0){let I=h.examples[0].length>o-15?h.examples[0].substring(0,o-18)+"...":h.examples[0];i.push(`${"".padStart(p+8)}{grey-fg}e.g. ${I}{/grey-fg}`)}}return i.push(""),i.push(`{grey-fg}Total patterns: ${s.length} (showing top ${c.length}){/grey-fg}`),i.join(`
|
|
1139
1139
|
`)}}});import*as H_e from"fs";import*as sx from"path";function _F(e,t=new Date){let n=t.getTime()-e.getTime();if(n<0)return"just now";let r=Math.floor(n/1e3);if(r<60)return"just now";let o=Math.floor(r/60);if(o<60)return`${o}m ago`;let i=Math.floor(o/60);return i<24?`${i}h ago`:`${Math.floor(i/24)}d ago`}function Z_e(e,t,n=new Date){let r=[],o=e.slice(0,G_e);for(let i of o){let s;try{s=H_e.statSync(i).mtime}catch{continue}let l=t.extractSessionLabel(i)||"Untitled session",p=sx.basename(i,sx.extname(i)),h=p.length>8?p.substring(0,8):p,g=_F(s,n),v=n.getTime()-s.getTime()<q_e;r.push({sessionPath:i,label:l,sessionId:h,age:g,isActive:v,providerId:t.id})}return r}function QWe(e,t=new Date){let n=e.sessionId||sx.basename(e.filePath,sx.extname(e.filePath)),r=n.length>8?n.substring(0,8):n,o=new Date(e.modifiedAt);return{sessionPath:e.filePath,label:e.firstUserPrompt||"Untitled session",sessionId:r,age:_F(o,t),isActive:t.getTime()-o.getTime()<q_e,providerId:e.provider}}async function K_e(e,t,n=new Date){let{previews:r}=await dh(e,{workspacePath:t,limit:G_e});return r.map(o=>QWe(o,n))}var fJ,G_e,q_e,pJ=B(()=>{"use strict";Pt();fJ={"claude-code":{badge:"CC",color:"green"},opencode:{badge:"OC",color:"cyan"},codex:{badge:"CX",color:"yellow"}},G_e=50,q_e=6e4});var OWe,NWe,ax,xF,c1=B(()=>{"use strict";OWe="SIDEKICK",NWe="Agent Hub",ax=[" {bold}{magenta-fg} ___ ___ ___ ___ _ _____ ___ _ __{/magenta-fg}{/bold}"," {bold}{magenta-fg}/ __|_ _| \\| __| |/ /_ _/ __| |/ /{/magenta-fg}{/bold}"," {bold}{magenta-fg}\\__ \\| || |) | _|| ' < | | (__| ' < {/magenta-fg}{/bold}"," {bold}{magenta-fg}|___/___|___/|___|_|\\_\\___\\___|_|\\_\\{/magenta-fg}{/bold}",` {grey-fg}${NWe}{/grey-fg}`],xF=`{bold}{magenta-fg}${OWe}{/magenta-fg}{/bold}`});function Y_e(e){return e==="grey"?"gray":e}function Su(e){if(!e)return null;if(!e.includes("{"))return e;let t=[],n=[{}],r=0,o=0;V_e.lastIndex=0;let i;for(;(i=V_e.exec(e))!==null;){let c=e.slice(r,i.index);c&&t.push(J_e(c,MC(n),o++)),r=i.index+i[0].length;let l=i[1]==="/",p=i[2];if(l){let h=-1;for(let g=n.length-1;g>0;g--)if(n[g].tag===p){h=g;break}h>0&&n.splice(h)}else if(p==="bold")n.push({...MC(n),tag:p,bold:!0});else if(p==="underline")n.push({...MC(n),tag:p,underline:!0});else if(p.endsWith("-fg")){let h=p.slice(0,-3);n.push({...MC(n),tag:p,color:Y_e(h)})}else if(p.endsWith("-bg")){let h=p.slice(0,-3);n.push({...MC(n),tag:p,backgroundColor:Y_e(h)})}else n.push({...MC(n),tag:p})}let s=e.slice(r);return s&&t.push(J_e(s,MC(n),o++)),t.length===0?null:t.length===1?t[0]:(0,cx.jsx)(cx.Fragment,{children:t})}function MC(e){return e[e.length-1]}function J_e(e,t,n){return t.bold||t.underline||t.color||t.backgroundColor?(0,cx.jsx)(j,{bold:t.bold,underline:t.underline,color:t.color,backgroundColor:t.backgroundColor,children:e},n):(0,cx.jsx)(j,{children:e},n)}var cx,V_e,QC=B(async()=>{"use strict";await ii();cx=Me(On(),1);V_e=/\{(\/?)([^}]+)\}/g});function zWe(e){if(new Set(e.map(o=>o.providerId).filter(Boolean)).size<=1)return null;let n=[],r=new Map;for(let o=0;o<e.length;o++){let i=e[o].providerId||"unknown";r.has(i)||r.set(i,[]),r.get(i).push(o)}for(let[o,i]of r){n.push({type:"header",providerId:o});for(let s of i)n.push({type:"item",index:s})}return n.push({type:"item",index:e.length}),{rows:n,selectableCount:e.length+1}}function FWe(e,t,n){let r=t?t.rows.filter(o=>o.type==="item")[n]?.index:n;return r===void 0||r===e.length?null:e[r]?.sessionPath??null}function UWe({items:e,onSelect:t}){let[n,r]=(0,W_e.useState)(0),{exit:o}=tm(),{isRawModeSupported:i}=Ka(),s=zWe(e),c=e.length+1;Cd((v,E)=>{if(v==="q"||E.escape||E.ctrl&&v==="c"){o();return}if(v==="j"||E.downArrow){r(I=>Math.min(I+1,c-1));return}if(v==="k"||E.upArrow){r(I=>Math.max(I-1,0));return}if(E.return){t(FWe(e,s,n));return}},{isActive:i});let l=process.stdout.rows||24,p=Math.max(5,l-15);function h(v,E){if(v===e.length)return(0,zr.jsx)(Ze,{children:(0,zr.jsxs)(j,{inverse:E,children:[(0,zr.jsx)(j,{color:"yellow",children:"+"})," Wait for a new session to start..."]})},"wait");let I=e[v],x=I.isActive?"\u25CF":"\u25CB",_=I.isActive?"green":"gray",T=I.providerId?fJ[I.providerId]:null,M=I.label.length>40?I.label.substring(0,37)+"...":I.label;return(0,zr.jsx)(Ze,{children:(0,zr.jsxs)(j,{inverse:E,children:[T&&(0,zr.jsxs)(j,{color:T.color,children:["[",T.badge,"]"]})," ",(0,zr.jsx)(j,{color:_,children:x})," ",M.padEnd(40)," ",(0,zr.jsx)(j,{color:"gray",children:I.age.padEnd(9)})," ",(0,zr.jsx)(j,{color:"gray",children:I.sessionId}),I.isActive?(0,zr.jsx)(j,{color:"green",children:" LIVE"}):""]})},I.sessionPath)}function g(){if(s){let x=s.rows,_=0,T=[];for(let H=0;H<x.length;H++)x[H].type==="item"&&T.push(H);let M=T[n]??0,$=Math.max(0,Math.min(M-Math.floor(p/2),x.length-p)),z=Math.max(0,$),U=Math.min(x.length,z+p),se=[];_=0;for(let H=0;H<x.length;H++){if(H<z||H>=U){x[H].type==="item"&&_++;continue}let ie=x[H];if(ie.type==="header"){let oe=PWe[ie.providerId]||ie.providerId,W=fJ[ie.providerId];se.push((0,zr.jsxs)(Ze,{children:[(0,zr.jsxs)(j,{dimColor:!0,children:["\u2500\u2500"," "]}),W&&(0,zr.jsx)(j,{color:W.color,children:oe}),!W&&(0,zr.jsx)(j,{children:oe}),(0,zr.jsxs)(j,{dimColor:!0,children:[" ","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"]})]},`hdr-${ie.providerId}`))}else{let oe=_===n;se.push(h(ie.index,oe)),_++}}return se}let v=Math.max(0,Math.min(n-Math.floor(p/2),c-p)),E=Math.max(0,v),I=Math.min(c,E+p);return Array.from({length:I-E},(x,_)=>{let T=E+_;return h(T,T===n)})}return(0,zr.jsxs)(Ze,{flexDirection:"column",width:"100%",height:l,children:[(0,zr.jsx)(Ze,{justifyContent:"center",marginTop:1,children:(0,zr.jsx)(Ze,{flexDirection:"column",width:50,children:ax.map((v,E)=>(0,zr.jsx)(j,{children:Su(v)},`logo-${E}`))})}),(0,zr.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",marginX:2,flexGrow:1,children:[(0,zr.jsxs)(j,{color:"magenta",children:[" Sessions (",e.length,") "]}),g()]}),(0,zr.jsx)(Ze,{height:1,children:(0,zr.jsxs)(j,{children:[" ",Su(xF)," ",(0,zr.jsx)(j,{color:"gray",children:"Session Picker"})," ",(0,zr.jsxs)(j,{bold:!0,children:["\u2191","/","\u2193"]})," ","navigate ",(0,zr.jsx)(j,{bold:!0,children:"Enter"})," select ",(0,zr.jsx)(j,{bold:!0,children:"q"})," quit"]})})]})}async function X_e(e,t,n){let{render:r}=await ii().then(()=>i1),o;if(n&&n.length>0)o=await K_e([e,...n],t);else{let i=e.findAllSessions(t);if(i.length===0)return{sessionPath:null};o=Z_e(i,e)}return o.length===0?{sessionPath:null}:new Promise((i,s)=>{let c=r((0,zr.jsx)(UWe,{items:o,onSelect:l=>{c.unmount();let p=o.find(h=>h.sessionPath===l);i({sessionPath:l,providerId:p?.providerId})}}));c.waitUntilExit().then(()=>{s(new Error("quit"))}).catch(s)})}var W_e,zr,PWe,exe=B(async()=>{"use strict";W_e=Me(fn(),1);await ii();pJ();c1();await QC();zr=Me(On(),1),PWe={"claude-code":"Claude Code",opencode:"OpenCode",codex:"Codex"}});function txe(){return`{grey-fg}${MT()}{/grey-fg}`}var nxe=B(()=>{"use strict";Pt()});function Ya(){let[e,t]=(0,wF.useState)({columns:process.stdout.columns||80,rows:process.stdout.rows||24});return(0,wF.useEffect)(()=>{let n=()=>{t({columns:process.stdout.columns||80,rows:process.stdout.rows||24})};return process.stdout.on("resize",n),()=>{process.stdout.off("resize",n)}},[]),e}var wF,Gh=B(()=>{"use strict";wF=Me(fn(),1)});function LWe(e,t,n){return Math.max(0,Math.min(e,Math.max(0,t-n)))}function rxe({totalItems:e,viewportHeight:t}){let[n,r]=(0,Va.useState)(0),[o,i]=(0,Va.useState)(0);(0,Va.useEffect)(()=>{if(e===0){r(0),i(0);return}r(_=>Math.min(_,e-1)),i(_=>LWe(_,e,t))},[e,t]);let s=(0,Va.useCallback)((_,T)=>{if(t<=0||e<=0)return 0;let M=T;_<M&&(M=_),_>=M+t&&(M=_-t+1);let $=Math.max(0,e-t);return Math.max(0,Math.min(M,$))},[e,t]),c=(0,Va.useCallback)(()=>{r(_=>{let T=Math.min(_+1,e-1);return i(M=>s(T,M)),T})},[e,s]),l=(0,Va.useCallback)(()=>{r(_=>{let T=Math.max(_-1,0);return i(M=>s(T,M)),T})},[s]),p=(0,Va.useCallback)(()=>{r(0),i(0)},[]),h=(0,Va.useCallback)(()=>{let _=Math.max(0,e-1);r(_),i(T=>s(_,T))},[e,s]),g=(0,Va.useCallback)(()=>{i(_=>{let T=Math.max(0,e-t);return Math.min(_+1,T)})},[e,t]),v=(0,Va.useCallback)(()=>{i(_=>Math.max(_-1,0))},[]),E=(0,Va.useCallback)(()=>{i(_=>{let T=Math.max(0,e-t);return Math.min(_+t,T)}),r(_=>Math.min(_+t,e-1))},[e,t]),I=(0,Va.useCallback)(()=>{i(_=>Math.max(_-t,0)),r(_=>Math.max(_-t,0))},[t]),x=(0,Va.useCallback)(_=>{let T=Math.max(0,Math.min(_,e-1));r(T),i(M=>s(T,M))},[e,s]);return{scrollOffset:o,selectedIndex:n,selectNext:c,selectPrev:l,selectFirst:p,selectLast:h,scrollDown:g,scrollUp:v,scrollPageDown:E,scrollPageUp:I,setSelected:x}}var Va,oxe=B(()=>{"use strict";Va=Me(fn(),1)});function ixe(e,t){return Math.max(0,Math.min(e,Math.max(0,t-1)))}function ux(e,t){let n=Math.max(1,t-2);return Math.max(0,e-n)}function sxe(e,t,n,r){return e!==t||n>r}var u1=B(()=>{"use strict"});function axe(e,t){let n=Math.max(1,e);return Math.max(1,n-(t>n?2:0))}function cxe(e,t){let n=0;for(let r=0;r<t.length;r++){let o=String(t[r].shortcutKey).length+t[r].title.length+2;if(e>=n&&e<n+o)return r;n+=o}return null}function uxe(e,t,n,r){let o=t+1;for(let i=0;i<n.length;i++){let s=n[i].length+(i===r?3:2);if(e>=o&&e<o+s)return i;o+=s}return null}function lxe(e,t,n){let r=e-3-(t>0?1:0);if(r<0)return null;let o=t+r;return o<n?o:null}var dxe=B(()=>{"use strict"});function fxe({panels:e,activeIndex:t,layoutMode:n}){let r=jWe[n]||n;return(0,vl.jsxs)(Ze,{height:1,width:"100%",children:[(0,vl.jsx)(Ze,{flexGrow:1,children:e.map((o,i)=>(0,vl.jsx)(Ze,{marginRight:1,children:i===t?(0,vl.jsxs)(j,{bold:!0,underline:!0,color:"magenta",children:[o.shortcutKey," ",o.title]}):(0,vl.jsxs)(vl.Fragment,{children:[(0,vl.jsx)(j,{dimColor:!0,children:o.shortcutKey}),(0,vl.jsxs)(j,{color:"gray",children:[" ",o.title]})]})},o.id))}),(0,vl.jsx)(Ze,{children:(0,vl.jsxs)(j,{dimColor:!0,children:["z: ",r," ","\u25B8"]})})]})}var vl,jWe,pxe=B(async()=>{"use strict";await ii();vl=Me(On(),1),jWe={normal:"Normal",expanded:"Expanded","wide-side":"Wide Side"}});function GWe(e,t){if(e.replace(HWe,"").length<=t)return e;let r=0,o=e.length,i=0;for(;i<e.length;){if(e[i]==="{"){let s=e.indexOf("}",i);if(s!==-1){i=s+1;continue}}if(r++,r>=t-1){o=i+1;break}i++}return e.substring(0,o)+"\u2026"}function qWe(e,t){if(!t)return e;let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r;try{r=new RegExp(`(${n})`,"gi")}catch{return e}return e.split(/(\{\/?\w[\w-]*\})/g).map(i=>i.startsWith("{")&&i.endsWith("}")?i:i.replace(r,"{blue-bg}{white-fg}$1{/white-fg}{/blue-bg}")).join("")}function mxe({items:e,selectedIndex:t,scrollOffset:n,focused:r,width:o,viewportHeight:i,panelTitle:s,sessionFilterActive:c,emptyStateHint:l,filterString:p}){let h=r?"magenta":"gray",g=r?"double":"single",v=Math.max(1,o-3),E=e.slice(n,n+i),I=n>0,x=n+i<e.length;return(0,to.jsxs)(Ze,{width:o,flexDirection:"column",borderStyle:g,borderColor:h,overflow:"hidden",children:[(0,to.jsx)(Ze,{children:(0,to.jsxs)(j,{color:h,children:[" ",s," (",e.length,")"," "]})}),I&&(0,to.jsx)(Ze,{justifyContent:"center",width:v,children:(0,to.jsx)(j,{color:"gray",children:"\u25B2"})}),E.map((_,T)=>{let $=n+T===t,z=$?"\u25B8":" ",U=GWe(_.label,v-2);return p&&(U=qWe(U,p)),(0,to.jsx)(Ze,{width:v,children:$?(0,to.jsxs)(j,{inverse:!0,children:[(0,to.jsx)(j,{bold:!0,children:z})," ",Su(U)]}):(0,to.jsxs)(j,{children:[z," ",Su(U)]})},_.id)}),e.length===0&&i>=3&&(0,to.jsxs)(to.Fragment,{children:[(0,to.jsx)(Ze,{width:v,children:(0,to.jsx)(j,{children:" "})},"empty-hint-pad"),(0,to.jsx)(Ze,{justifyContent:"center",width:v,children:(0,to.jsx)(j,{color:"gray",children:c?"No items in this session":"No items yet"})},"empty-hint-1"),c&&(0,to.jsxs)(Ze,{justifyContent:"center",width:v,children:[(0,to.jsx)(j,{color:"gray",children:"Press "}),(0,to.jsx)(j,{color:"magenta",bold:!0,children:"f"}),(0,to.jsx)(j,{color:"gray",children:" to see all"})]},"empty-hint-2"),!c&&l&&i>=5&&(0,to.jsx)(Ze,{justifyContent:"center",width:v,children:(0,to.jsx)(j,{dimColor:!0,children:l})},"empty-hint-desc")]}),E.length<i&&Array.from({length:Math.max(0,i-E.length-(e.length===0&&i>=3?c||!c&&l&&i>=5?3:2:0))},(_,T)=>(0,to.jsx)(Ze,{width:v,children:(0,to.jsx)(j,{children:" "})},`empty-${T}`)),x&&(0,to.jsx)(Ze,{justifyContent:"center",width:v,children:(0,to.jsx)(j,{color:"gray",children:"\u25BC"})})]})}var to,HWe,hxe=B(async()=>{"use strict";await ii();await QC();to=Me(On(),1),HWe=/\{\/?\w[\w-]*\}/g});function gxe({tabs:e,activeIndex:t}){return e.length===0?(0,qh.jsx)(Ze,{height:1}):(0,qh.jsxs)(Ze,{height:1,children:[(0,qh.jsx)(j,{children:" "}),e.map((n,r)=>(0,qh.jsx)(Ze,{marginRight:1,children:r===t?(0,qh.jsxs)(j,{bold:!0,color:"magenta",children:["\u25B8 ",n.label]}):(0,qh.jsxs)(j,{color:"gray",children:[" ",n.label]})},n.label)),e.length>1&&(0,qh.jsx)(j,{color:"gray",children:" \u2190 [ ] \u2192"})]})}var qh,Axe=B(async()=>{"use strict";await ii();qh=Me(On(),1)});function yxe({content:e,scrollOffset:t,viewportHeight:n,focused:r}){let o=r?"magenta":"gray",i=r?"double":"single",s=e?e.split(`
|
|
1140
|
-
`):[],c=s.length,l=ixe(t,c),p=l>0,h=p?1:0,g=c>l+n-1?1:0,v=Math.max(1,n-h-g),E=s.slice(l,l+v),I=l+v<c;return(0,Zh.jsxs)(Ze,{flexDirection:"column",flexGrow:1,borderStyle:i,borderColor:o,paddingLeft:1,children:[p&&(0,Zh.jsx)(Ze,{justifyContent:"center",children:(0,Zh.jsxs)(j,{color:"gray",children:["\u25B2 (",l," more)"]})}),E.map((x,_)=>(0,Zh.jsx)(j,{wrap:"wrap",children:Su(x)},l+_)),E.length<v&&Array.from({length:v-E.length},(x,_)=>(0,Zh.jsx)(j,{children:" "},`pad-${_}`)),I&&(0,Zh.jsx)(Ze,{justifyContent:"center",children:(0,Zh.jsxs)(j,{color:"gray",children:["\u25BC (",c-l-v," more)"]})})]})}var Zh,vxe=B(async()=>{"use strict";await ii();await QC();u1();Zh=Me(On(),1)});function mJ({eventCount:e,providerName:t,permissionMode:n,focusTarget:r,panelHints:o,sessionFilter:i,filterString:s,matchCount:c,totalCount:l,updateInfo:p,providerStatus:h,openaiStatus:g,mouseEnabled:v,dataBadge:E,activeAccount:I}){let x=e>0?`${e} events`:"waiting...",_=n==="bypassPermissions"?"red":n==="acceptEdits"?"magenta":n==="plan"?"green":void 0,T=n==="bypassPermissions"?"BYPASS":n==="acceptEdits"?"EDITS":n==="plan"?"PLAN":void 0,M=h?RC(h):null,$=g?RC(g):null;return(0,pt.jsxs)(Ze,{height:1,width:"100%",children:[(0,pt.jsxs)(Ze,{children:[(0,pt.jsx)(j,{children:Su(xF)}),(0,pt.jsxs)(j,{dimColor:!0,children:[" v","0.28.0"]}),p&&(0,pt.jsxs)(j,{color:"yellow",children:[" (v",p.latest,")"]})]}),(0,pt.jsxs)(Ze,{flexGrow:1,justifyContent:"center",children:[t&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:"cyan",children:t})]}),I&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsxs)(j,{color:I.color,children:["\u2394"," ",I.label]})]}),n&&n!=="default"&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:_,children:T})]}),(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{children:x}),M?.visible&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:M.color,children:M.summary})]}),$?.visible&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:$.color,children:$.summary})]}),v===!1&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:"yellow",children:"MOUSE OFF"})]}),E&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:E.color,children:E.text})]}),s&&(0,pt.jsxs)(j,{color:"yellow",children:[" ",'filter: "',s,'" (',c??0,"/",l??0,")"]}),i&&(0,pt.jsxs)(j,{color:"magenta",children:[" ",i]})]}),(0,pt.jsxs)(Ze,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:["\u2502"," "]}),r==="side"?(0,pt.jsxs)(j,{children:[(0,pt.jsx)(j,{bold:!0,children:"\u2191\u2193"}),(0,pt.jsx)(j,{dimColor:!0,children:" nav "}),(0,pt.jsx)(j,{bold:!0,children:"Tab"}),(0,pt.jsx)(j,{dimColor:!0,children:" detail "}),o,(0,pt.jsx)(j,{bold:!0,children:"/"}),(0,pt.jsx)(j,{dimColor:!0,children:" filter "}),(0,pt.jsx)(j,{bold:!0,children:"?"}),(0,pt.jsx)(j,{dimColor:!0,children:" help "}),(0,pt.jsx)(j,{bold:!0,children:"q"}),(0,pt.jsx)(j,{dimColor:!0,children:" quit"})]}):(0,pt.jsxs)(j,{children:[(0,pt.jsx)(j,{bold:!0,children:"j/k"}),(0,pt.jsx)(j,{dimColor:!0,children:" scroll "}),(0,pt.jsx)(j,{bold:!0,children:"[]"}),(0,pt.jsx)(j,{dimColor:!0,children:" tab "}),(0,pt.jsx)(j,{bold:!0,children:"Tab"}),(0,pt.jsx)(j,{dimColor:!0,children:" side "}),o,(0,pt.jsx)(j,{bold:!0,children:"?"}),(0,pt.jsx)(j,{dimColor:!0,children:" help "}),(0,pt.jsx)(j,{bold:!0,children:"q"}),(0,pt.jsx)(j,{dimColor:!0,children:" quit"})]})]})]})}var pt,Cxe=B(async()=>{"use strict";lF();await ii();c1();await QC();pt=Me(On(),1)});function Sxe(e=ZWe){let[t,n]=(0,kF.useState)(0);return(0,kF.useEffect)(()=>{let r=setInterval(()=>{n(o=>(o+1)%Exe.length)},e);return()=>clearInterval(r)},[e]),Exe[t]}var kF,Exe,ZWe,bxe=B(()=>{"use strict";kF=Me(fn(),1),Exe=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2807","\u280F"],ZWe=80});function _xe({panelCount:e}){let t=Sxe(),n=(0,Ixe.useMemo)(()=>MT(),[]),{columns:r}=Ya(),o=e&&e>1?`1-${Math.min(e,9)}`:"1-9";return(0,si.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",paddingX:2,paddingY:1,width:Math.min(60,r-2),children:[ax.map((i,s)=>(0,si.jsx)(j,{children:Su(i)},s)),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{color:"gray",children:[" ",n]}),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{children:[" ",(0,si.jsx)(j,{color:"magenta",children:t})," ",(0,si.jsx)(j,{color:"gray",children:"Waiting for session events..."})]}),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{children:[" ",(0,si.jsx)(j,{color:"gray",children:"Navigate:"})," ",(0,si.jsx)(j,{bold:!0,children:o})," jump ",(0,si.jsx)(j,{bold:!0,children:"?"})," ","help ",(0,si.jsx)(j,{bold:!0,children:"q"})," quit"]}),(0,si.jsx)(j,{children:" "}),(0,si.jsx)(j,{color:"gray",children:" Start a Claude Code, OpenCode, or Codex session"}),(0,si.jsx)(j,{color:"gray",children:" in another terminal and events will appear here."}),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{children:[" ",(0,si.jsx)(j,{color:"gray",children:"Or use "}),(0,si.jsx)(j,{bold:!0,children:"--replay"}),(0,si.jsx)(j,{color:"gray",children:" to replay an existing session."})]})]})}var Ixe,si,xxe=B(async()=>{"use strict";Ixe=Me(fn(),1);await ii();bxe();Pt();c1();await QC();Gh();si=Me(On(),1)});function ai(e,t,n=14,r=54){let o=n-e.length,i=Math.max(1,r-n-t.length),s="\xB7".repeat(i);return(0,xi.jsxs)(j,{children:[" ",(0,xi.jsx)(j,{bold:!0,children:e})," ".repeat(Math.max(0,o))," ",(0,xi.jsx)(j,{dimColor:!0,children:s})," ",t]})}function wxe({panels:e,activePanelIndex:t,scrollOffset:n,onClampScroll:r}){let{columns:o,rows:i}=Ya(),s=e[t],c=s.getActions(),l=s.getKeybindings?.()||[],p=[];p.push((0,xi.jsx)(j,{bold:!0,children:" Panels"}));for(let _ of e)p.push(ai(String(_.shortcutKey),_.title));if(p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsx)(j,{bold:!0,children:" Navigation"})),p.push(ai("Tab","Toggle side / detail focus")),p.push(ai("j / \u2193","Next item / scroll down")),p.push(ai("k / \u2191","Prev item / scroll up")),p.push(ai("g / G","First / last item")),p.push(ai("Enter","Focus detail pane")),p.push(ai("h / \u2190","Return to side")),p.push(ai("[ / ]","Cycle detail tabs")),p.push(ai("z","Cycle layout mode")),p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsx)(j,{bold:!0,children:" Actions"})),p.push(ai("x","Context menu")),p.push(ai("/","Filter side list")),p.push(ai("f","Toggle session filter")),c.length>0||l.length>0){p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsxs)(j,{bold:!0,children:[" ",s.title," Actions"]}));for(let _ of c)p.push(ai(_.key,_.label));for(let _ of l)p.push(ai(_.keys.join("/"),_.label))}p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsx)(j,{bold:!0,children:" General"})),p.push(ai("R","Refresh project data")),p.push(ai("r","Generate HTML report")),p.push(ai("p","Pin session (stop auto-switch)")),p.push(ai("s","Switch to pending session")),p.push(ai("A","Accounts: switch / undo")),p.push(ai("M","Toggle mouse capture (copy/select)")),p.push(ai("V","Version & changelog")),p.push(ai("?","Toggle this help")),p.push(ai("Esc","Close overlay / clear filter")),p.push(ai("q / Ctrl+C","Quit"));let h=Math.max(5,i-12),g=Math.max(0,p.length-h);hJ.default.useEffect(()=>{n>g&&r?.(g)},[n,g,r]);let v=Math.min(n,g),E=p.slice(v,v+h),I=v>0,x=v+h<p.length;return(0,xi.jsx)(Ze,{flexGrow:1,alignItems:"center",justifyContent:"center",children:(0,xi.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",paddingX:1,paddingY:1,width:Math.min(60,o-2),children:[ax.map((_,T)=>(0,xi.jsx)(j,{children:Su(_)},`logo-${T}`)),(0,xi.jsx)(j,{children:" "}),I?(0,xi.jsx)(j,{color:"gray",children:" \u25B2 scroll up (k)"}):(0,xi.jsx)(j,{children:" "}),E.map((_,T)=>(0,xi.jsx)(hJ.default.Fragment,{children:_},`row-${v+T}`)),x?(0,xi.jsx)(j,{color:"gray",children:" \u25BC scroll down (j)"}):(0,xi.jsx)(j,{children:" "})]})})}var hJ,xi,kxe=B(async()=>{"use strict";hJ=Me(fn(),1);await ii();c1();await QC();Gh();xi=Me(On(),1)});function Dxe({actions:e,selectedIndex:t}){let{columns:n,rows:r}=Ya();if(e.length===0)return(0,nm.jsx)(Ze,{});let o=Math.max(...e.map(s=>s.key.length+s.label.length+4),20),i=Math.min(o+6,50,n-2);return(0,nm.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",width:i,position:"absolute",marginLeft:Math.max(0,Math.floor((n-i)/2)),marginTop:Math.max(0,Math.floor((r-e.length-2)/2)),children:[(0,nm.jsx)(j,{color:"magenta",children:" Actions "}),e.map((s,c)=>(0,nm.jsx)(Ze,{children:c===t?(0,nm.jsxs)(j,{inverse:!0,children:[" ",(0,nm.jsx)(j,{bold:!0,children:s.key})," ",s.label]}):(0,nm.jsxs)(j,{children:[" ",(0,nm.jsx)(j,{bold:!0,children:s.key})," ",s.label]})},s.key))]})}var nm,Txe=B(async()=>{"use strict";await ii();Gh();nm=Me(On(),1)});function gJ({views:e,selectedIndex:t}){let{columns:n,rows:r}=Ya(),o=fB(e),i=Date.now(),s=6+o.name+(o.email?o.email+2:0)+(o.plan?o.plan+2:0)+24,c=Math.min(Math.max(44,s),n-2),l=e.length+6,p=null,h=-1;return(0,Ja.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",width:c,position:"absolute",marginLeft:Math.max(0,Math.floor((n-c)/2)),marginTop:Math.max(0,Math.floor((r-l)/2)),paddingX:1,children:[(0,Ja.jsx)(j,{color:"magenta",children:" Accounts "}),e.length===0&&(0,Ja.jsx)(j,{dimColor:!0,children:"No saved accounts. Run: sidekick accounts add"}),e.map(g=>{h++;let v=g.providerId!==p?ms[g.providerId]:null;p=g.providerId;let E=S_(g,i);return(0,Ja.jsxs)(Ze,{flexDirection:"column",children:[v&&(0,Ja.jsx)(j,{bold:!0,children:v}),(0,Ja.jsxs)(j,{inverse:h===t,children:[" ",(0,Ja.jsx)(j,{color:"green",children:g.isActive?"* ":" "}),E.name.padEnd(o.name),o.email?(0,Ja.jsxs)(j,{dimColor:!0,children:[" ",E.email.padEnd(o.email)]}):""," ",(0,Ja.jsxs)(j,{color:E.badge.color,children:[E.badge.glyph," ",E.badge.state]})]})]},`${g.providerId}:${g.id}`)}),(0,Ja.jsxs)(j,{dimColor:!0,children:[(0,Ja.jsx)(j,{bold:!0,children:"Enter"})," switch ",(0,Ja.jsx)(j,{bold:!0,children:"u"})," undo ",(0,Ja.jsx)(j,{bold:!0,children:"a/l/s"})," via CLI"," ",(0,Ja.jsx)(j,{bold:!0,children:"Esc"})," close"]})]})}var Ja,Bxe=B(async()=>{"use strict";await ii();gC();Gh();Ja=Me(On(),1)});function Rxe({filterString:e,filterMode:t,filterError:n}){let{rows:r}=Ya();return(0,Sd.jsxs)(Ze,{position:"absolute",marginTop:r-2,width:"100%",height:1,children:[YWe.map(o=>{let{key:i,label:s}=KWe[o];return(0,Sd.jsx)(j,{children:o===t?(0,Sd.jsxs)(j,{bold:!0,color:"magenta",children:["[",i,"]",s," "]}):(0,Sd.jsxs)(j,{color:"gray",children:["[",i,"]",s," "]})},o)}),(0,Sd.jsxs)(j,{bold:!0,color:"magenta",children:[" ","/"," "]}),n?(0,Sd.jsx)(j,{color:"red",children:e}):(0,Sd.jsx)(j,{children:e}),(0,Sd.jsx)(j,{color:"gray",children:"\u2588"}),n&&(0,Sd.jsxs)(j,{color:"red",children:[" ",n]}),t==="date"&&!e&&(0,Sd.jsx)(j,{color:"gray",children:" today \xB7 yesterday \xB7 2d \xB7 1w \xB7 YYYY-MM-DD \xB7 >expr \xB7 <expr"})]})}var Sd,KWe,YWe,$xe=B(async()=>{"use strict";await ii();Gh();Sd=Me(On(),1),KWe={substring:{key:"S",label:"Substr"},fuzzy:{key:"F",label:"Fuzzy"},regex:{key:"R",label:"Regex"},date:{key:"D",label:"Date"}},YWe=["substring","fuzzy","regex","date"]});function Qxe({entries:e,scrollOffset:t,onClampScroll:n}){let{columns:r,rows:o}=Ya(),i=Math.min(64,r-2),s=Math.max(o-12,10),c=[],l=e[0]?.date||"";c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsxs)(j,{bold:!0,color:"cyan",children:["Terminal Dashboard v","0.28.0"]}),l?(0,no.jsxs)(j,{color:"gray",children:[" \u2014 ",l]}):null]},"ver")),c.push((0,no.jsx)(j,{children:" "},"sep"));for(let I=0;I<e.length;I++){let x=e[I];I>0&&c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsxs)(j,{bold:!0,children:["v",x.version]}),(0,no.jsxs)(j,{color:"gray",children:[" \u2014 ",x.date]})]},`v-${I}`));for(let _ of x.sections){c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsx)(j,{bold:!0,color:"yellow",children:_.heading})]},`h-${I}-${_.heading}`));for(let T=0;T<_.items.length;T++){let M=i-8,$=_.items[T];$.length>M&&($=$.slice(0,M-1)+"\u2026"),c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsx)(j,{color:"gray",children:"\u2022"})," ",$]},`item-${I}-${_.heading}-${T}`))}}I<e.length-1&&c.push((0,no.jsx)(j,{children:" "},`gap-${I}`))}let p=Math.max(0,c.length-s);Mxe.default.useEffect(()=>{t>p&&n?.(p)},[t,p,n]);let h=Math.min(t,p),g=c.slice(h,h+s),v=h>0,E=h+s<c.length;return(0,no.jsx)(Ze,{flexGrow:1,alignItems:"center",justifyContent:"center",children:(0,no.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",paddingX:1,paddingY:1,width:i,children:[(0,no.jsxs)(j,{children:[" ",(0,no.jsxs)(j,{bold:!0,color:"magenta",children:["\u26A1"," W H A T ' S N E W"]})]}),(0,no.jsx)(j,{children:" "}),v&&(0,no.jsx)(j,{color:"gray",children:" \u25B2 scroll up (k)"}),g,E&&(0,no.jsx)(j,{color:"gray",children:" \u25BC scroll down (j)"}),(0,no.jsx)(j,{children:" "}),(0,no.jsxs)(j,{color:"gray",children:[" ","Full changelog:"," ",(0,no.jsx)(j,{color:"cyan",children:"https://cesarandreslopez.github.io/sidekick-agent-hub/changelog/"})]}),(0,no.jsx)(j,{children:" "}),(0,no.jsxs)(j,{color:"gray",children:[" ","Press ",(0,no.jsx)(j,{bold:!0,children:"Esc"})," or ",(0,no.jsx)(j,{bold:!0,children:"V"})," to close"]})]})})}var Mxe,no,Oxe=B(async()=>{"use strict";Mxe=Me(fn(),1);await ii();Gh();no=Me(On(),1)});function Nxe({columns:e,rows:t}){return(0,lx.jsx)(Ze,{flexDirection:"column",width:e,height:t,justifyContent:"center",alignItems:"center",children:(0,lx.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"red",paddingX:2,paddingY:1,children:[(0,lx.jsx)(j,{color:"red",children:"Terminal too small"}),(0,lx.jsxs)(j,{color:"gray",children:["Need at least 60x15 (current: ",e,"x",t,")"]})]})})}var lx,Pxe=B(async()=>{"use strict";await ii();lx=Me(On(),1)});function AJ({toast:e,row:t=0}){let{columns:n}=Ya(),r=VWe[e.severity]||"cyan",o=JWe[e.severity]||"\u25CF",i=Math.max(16,Math.min(56,n-10)),s=e.message.length>i?e.message.substring(0,i-3)+"...":e.message;return(0,DF.jsx)(Ze,{position:"absolute",marginLeft:Math.max(0,n-s.length-8),marginTop:t*3,borderStyle:"single",borderColor:r,paddingX:1,children:(0,DF.jsxs)(j,{color:r,children:[o," ",s]})})}var DF,VWe,JWe,zxe=B(async()=>{"use strict";await ii();Gh();DF=Me(On(),1),VWe={error:"red",warning:"yellow",info:"cyan"},JWe={error:"\u2718",warning:"\u26A0",info:"\u25CF"}});function yJ(e=process.stdout){e.isTTY&&(e.write("\x1B[?1000h"),e.write("\x1B[?1002h"),e.write("\x1B[?1006h"))}function dx(e=process.stdout){e.isTTY&&(e.write("\x1B[?1006l"),e.write("\x1B[?1002l"),e.write("\x1B[?1000l"))}var vJ=B(()=>{"use strict"});function Fxe(e){let t=typeof e=="string"?e:e.toString("utf-8");return Array.from(t.matchAll(WWe),XWe).filter(n=>n!==null)}function XWe(e){let t=parseInt(e[1],10),n=parseInt(e[2],10),r=parseInt(e[3],10),o=e[4]==="m",i=n-1,s=r-1,c=(t&4)!==0,l=(t&8)!==0,p=(t&16)!==0,h=t&-29;return h===64||h===65?{type:"scroll",button:"none",x:i,y:s,shift:c,meta:l,ctrl:p,scrollDirection:h===64?"up":"down"}:h>=32&&h<=34?{type:"drag",button:["left","middle","right"][h-32],x:i,y:s,shift:c,meta:l,ctrl:p}:h>=0&&h<=2?{type:o?"release":"click",button:["left","middle","right"][h],x:i,y:s,shift:c,meta:l,ctrl:p}:null}var WWe,CJ=B(()=>{"use strict";WWe=/\x1b\[<(\d+);(\d+);(\d+)([Mm])/g});function Uxe(e){return t=>{for(let n of Fxe(t))e.current(n)}}var Lxe=B(()=>{"use strict";CJ()});function eXe({active:e}){return Cd(()=>{},{isActive:e}),null}function BF({onMouse:e,enabled:t=!0,children:n}){let r=(0,TF.useRef)(e);r.current=e;let{isRawModeSupported:o}=Ka();return(0,TF.useEffect)(()=>{if(!t||!o)return;yJ();let i=Uxe(r);process.stdin.on("data",i);let s=()=>dx();return process.on("exit",s),()=>{process.stdin.removeListener("data",i),process.removeListener("exit",s),dx()}},[t,o]),(0,fx.jsxs)(fx.Fragment,{children:[(0,fx.jsx)(eXe,{active:o}),n]})}var TF,fx,jxe=B(async()=>{"use strict";TF=Me(fn(),1);await ii();vJ();Lxe();fx=Me(On(),1)});var EJ=B(async()=>{"use strict";vJ();CJ();await jxe()});var Gxe,Hxe=B(()=>{Gxe="# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.28.0] - 2026-10-18\n\n### Fixed\n\n- **Sessions under a custom Claude home are read** (bundled `sidekick-shared`). With `CLAUDE_CONFIG_DIR` set, `dashboard`, `dump`, `report`, `daily` / `weekly` / `monthly` / `sessions`, `blocks`, `search`, `doctor`, and plan reading follow the home Claude Code writes to instead of only `~/.claude`.\n- **Archived Codex sessions stay visible** (bundled `sidekick-shared`): sessions Codex moved to `archived_sessions/` are listed, found by id, and counted in usage reports.\n- **Long-running session watching stays bounded** (bundled `sidekick-shared`): `dashboard` and `dump` read a large backlog in chunks, skip a line over 16 MiB, and re-read a session file that is truncated, rewritten, or replaced from the start; the dashboard then drops the metrics built from the old content instead of counting the session twice.\n\n### Changed\n\n- The CLI's main bundle shrinks from 2.85 MB to 2.47 MB: it now bundles `sidekick-shared` from its tree-shakable ES-module build.\n\n## [0.27.6] - 2026-09-26\n\n### Added\n\n- `sidekick accounts doctor` adds a \"Claude credential stores\" section: stored credentials Sidekick owns that no account uses, a second copy of the live login, and unreadable (truncated) credentials. `--fix` repairs them after asking; `--yes` skips the prompt, and `--json` output lists what was repaired. Ownership is proven by a ledger and a Keychain comment tag, never by the item name.\n\n### Fixed\n\n- **Claude logins are no longer invalidated by Sidekick** (bundled `sidekick-shared`). Claude Code rotates the refresh token on every refresh, so every usable copy of a login but one dies with \"Not logged in \xB7 Please run /login\"; Sidekick now keeps exactly one.\n - Keychain writes larger than about 4 KB are no longer truncated into an unreadable credential, and every write is read back before it counts.\n - The live account no longer keeps a second usable copy in its profile directory; `accounts switch` saves the outgoing login first (even with `--force`), holds Claude Code's refresh lock, never overwrites a newer login, and keeps the live MCP server tokens.\n - Keep-alive never refreshes a copy of a live login. `accounts shell` / `env` for the live account use the normal Claude home.\n - `sidekick account --launcher` scripts resolve the account's home when they run instead of pinning a profile directory.\n - In a shell from `sidekick accounts env` or `shell`, commands no longer remove that account's login as a supposed second copy of the live login.\n- **Codex logins get the same protection** (bundled `sidekick-shared`): verified private backups replace runnable profile copies and timestamped stashes, `accounts switch` is refused while Codex CLI, app, or IDE sessions run (`--force` does not bypass it) and is journaled so an interrupted switch finishes or rolls back, and keep-alive refreshes through `codex app-server`.\n- `accounts doctor` no longer syncs accounts or rewrites health metadata while inspecting, and `--fix` also repairs Codex duplicates, stale stashes, orphaned copies, and interrupted switches, honouring `--provider` and the confirmation prompt.\n\n## [0.27.5] - 2026-09-23\n\n### Added\n\n- `sidekick dump --prompts` prints every human prompt of Claude Code and Codex sessions grouped by session, for reading or classifying a whole session. The default is the most recent session with prompts.\n - **Selecting sessions.** `--session <id-or-prefix>` picks one session. `--all` takes every session of the project and its git worktrees, optionally narrowed by `--since <time>` (sessions active since then, returned whole) and `--limit <n>`.\n - **Extra content.** `--replies` adds the agent's final reply to each prompt, and `--signals` adds interrupts, rejected and failed tool calls, compactions, API errors, and rollbacks.\n - **Output.** `--format` accepts `text`, `markdown`, `json` (the full result, with bounds and stats), or `jsonl` (one session per line). Bounded calls continue automatically until every session is read, and a reader that stops early (`| head`) ends the dump quietly.\n - **Providers.** Both are read unless `--provider claude-code` or `--provider codex` is given; OpenCode exits with an error.\n\n## [0.27.4] - 2026-09-23\n\n### Changed\n\n- Bundles `sidekick-shared` 0.27.4 (new `sidekick-shared/node` exports and an optional abort signal for `collectUsageEvents()`); no CLI-visible changes.\n\n## [0.27.3] - 2026-09-23\n\n### Fixed\n\n- Token totals no longer double-count Claude Code split lines or repeated Codex `token_count` events (via `sidekick-shared` 0.27.3). This corrects `dump`, `report`, the dashboard, `daily`/`weekly`/`monthly`/`sessions`, and `blocks`; the usage cache rebuilds itself on first run.\n\n### Added\n\n- `sidekick dump` shows the session's subagents: text and markdown add \"Subagents (n)\" and \"Session total (incl. subagents)\", and `--format json` adds a `tokenSummary` block (`mainThread`, `subagents`, `subagentTotal`, `combined`). `sidekick report` adds the same cards.\n- The dashboard's Sessions panel leads its Tokens section with \"Total (incl. cache)\" and lists every bucket, then subagent and session totals (subagent transcripts are rescanned every 15 s). Its state file writes `context.totalTokens`.\n\n### Changed\n\n- Cache hit rate counts cache writes, per-event token suffixes and the event detail show cache-inclusive totals, and the dashboard's cost comes from `costUsd`. Claude subagent transcripts now count toward the usage reports under their parent session.\n\n## [0.27.2] - 2026-09-22\n\n### Changed\n\n- Bundles `sidekick-shared` 0.27.2 (streamed, resumable prompt history); no CLI-visible changes.\n\n## [0.27.1] - 2026-09-22\n\n### Changed\n\n- Bundles `sidekick-shared` 0.27.1 (prompt-history late answer metadata); no CLI-visible changes.\n\n## [0.27.0] - 2026-09-22\n\n### Changed\n\n- Dashboard session summaries sent through the OpenAI API use GPT-6 Luna (`gpt-6-luna`) instead of GPT-5.6 Luna; GPT-6 Sol and Luna sessions get pricing and context-window metadata via `sidekick-shared` 0.27.0.\n\n### Fixed\n\n- Cost estimates for Claude Opus 5.5 (`claude-opus-5-5`) sessions use its own rates ($4 / $20 per 1M tokens, $0.20 cache reads) instead of Opus 5's, via `sidekick-shared` 0.27.0.\n\n## [0.26.6] - 2026-09-16\n\n### Added\n\n- `sidekick accounts`: an interactive picker (arrow keys, `Enter` switch, `a` add, `l` sign in again, `r` remove, `s` shell, `u` undo) plus `list`, `add`, `switch`, `login`, `remove`, `shell`, `env`, `undo`, `doctor`, and `config` subcommands. Lists show credential health and expiry; switches print `\u2713 verified`, one line per running app that still holds the previous login, and the undo command; `env` renders bash/zsh/fish/PowerShell/cmd exports and `shell` opens a subshell or runs one command as a saved account on every platform.\n- `sidekick accounts doctor` reports per-account expiry, running `claude`/`codex` processes and desktop apps, the Codex credential-store mode, and the keep-alive state; `accounts config keep-alive on` makes the dashboard refresh inactive accounts hourly through the official CLIs.\n- Dashboard: `A` opens an accounts overlay (`Enter` switch, `u` undo) and the status bar shows the active account coloured by health.\n\n### Changed\n\n- Every `accounts` command first folds live logins into the registry and prints `Registered <email>` on stderr for logins it had never seen; `list` prints first-run guidance while all accounts were learned automatically.\n\n### Fixed\n\n- The dashboard status-bar account now follows the monitored provider (the Codex provider is displayed as `Codex CLI`, so the badge always showed the Claude account before), and the overlay's `u` undoes the provider that actually has a switch to revert instead of whichever provider has saved accounts.\n- The interactive picker reports the real outcome of `u` and `r`: a failed undo or remove shows the error instead of `Undone.` / `Removed \u2026`, and a successful undo shows the switch headline rather than the trailing hint.\n- `accounts switch --next` with no saved accounts says so instead of claiming two providers have accounts.\n\n### Deprecated\n\n- `sidekick account --\u2026` flags: still work, print the equivalent `sidekick accounts \u2026` command on stderr, and now delegate to the same actions. `--launcher` remains POSIX-only; `accounts shell` / `accounts env` are the cross-platform replacements.\n\n## [0.26.5] - 2026-09-15\n\n### Changed\n\n- `sidekick dashboard` newer-session detection reconciles each watched-file event with one stat, and catch-up polls cost one stat per unchanged directory instead of walking every session file.\n\n## [0.26.4] - 2026-09-09\n\n### Fixed\n\n- AI summary failures distinguish refresh-token rejection from expired conversations and recognize expired-login and reauthentication messages with guidance appropriate to the known credential kind.\n- Policy-denial messages, including HTTP 403 responses, direct users to review execution permissions.\n\n## [0.26.3] - 2026-09-09\n\n### Added\n\n- `sidekick status --json` includes `serviceStatus` evidence alongside existing Claude, OpenAI, and peak-hour fields. Human-readable output and dashboard details include multiple incidents, component associations, and separate check/provider-update timestamps.\n\n### Fixed\n\n- Status displays distinguish unavailable and partial evidence, including omitted incident data. Dashboard polling coalesces overlapping checks and cancels outstanding checks when stopped.\n- AI summary failures retain structured provider diagnoses and show appropriate authentication, session, service, connection, policy, runtime, and context guidance without automatic replay or provider switching.\n\n## [0.26.2] - 2026-09-06\n\n### Fixed\n\n- CLI live-only sessions no longer overwrite complete-history checkpoints. Older CLI checkpoints are invalidated and replayed once.\n- OpenCode dashboards replay history instead of restoring timestamp-only snapshots, preventing duplicate token totals on reopen.\n- Dashboard checkpoints save after complete event batches, use the current snapshot schema, and reject obsolete or incompatible consumer formats.\n- Project-scoped search passes the workspace path through shared provider discovery, including Codex and database-only OpenCode sessions.\n- Doctor honors `--provider`; unused integrations and missing saved accounts are informational when monitoring existing sessions.\n- Shared watchers preserve partial UTF-8 lines and use OpenCode's platform-specific data directory.\n\n## [0.26.1] - 2026-09-05\n\n### Changed\n\n- Direct OpenAI API dashboard summaries use GPT-5.6 Luna with reasoning disabled and a 1,024-token `max_completion_tokens` limit. Anthropic API summaries retain Haiku 4.5; native CLI summaries retain the user's model configuration.\n\n### Fixed\n\n- Shared model metadata verified on 2026-09-05 corrects fallback costs and context gauges for Fable 5.1, GPT-6 Astra, GPT-5.6, and GPT-5.4 mini/nano.\n- Codex `quota`, `quota --provider codex`, `quota --all`, and MCP quota queries fetch live utilization and reset credits on every call. Local samples no longer prevent API refreshes, including with `--refresh`.\n- Codex fallback output shows sample age and the failed API refresh reason; older logs no longer hide newer cached data.\n\n## [0.26.0] - 2026-09-05\n\n### Added\n\n- `sidekick statusline` reads the JSON Claude Code pipes to its status-line command (`SIDEKICK_STATUSLINE_STDIN=0` disables it), appends context %, session cost, and prompt-cache hit rate, and persists the official five-hour and seven-day limits to the quota snapshot and history stores, so every other command and dashboard sees them without a network call. Cached quota older than five minutes is labelled with its age\n- Global `--offline` (or `SIDEKICK_OFFLINE=1`) prices from the cached catalog only; global `--output-file <path>` writes a command's stdout to a file (not for `dashboard` or `mcp`)\n- `stats --csv` prints every recorded day; `dump --list --csv` and `quota history --csv` print their tables as CSV\n- `quota history --window 5h|7d|max` selects which limit the heatmap shows (default `5h`); the header names the window\n- The global `--json` flag applies to `tasks add`, `tasks done`, `note add`, `decision add` (returning the stored record) and to `report` (returning the output path)\n- The dashboard raises a toast when the five-hour window crosses 80% or 95%, or the seven-day window crosses 90%, once per reset window\n- `sidekick blocks [--active | --recent | --since <time>] [--csv] [--no-cache]` shows five-hour billing blocks computed from session logs (a block opens at the first usage event aligned to the UTC hour, lasts five hours, and a longer gap opens a new one) with cache-inclusive totals, cost provenance, burn rate, and \u2014 for the open block \u2014 projected end-of-block tokens and cost. Sessions are read once and cached by size and mtime; the table is labelled a local estimate and the official status-line sample is shown beneath it when present. `--since` accepts an ISO date, `YYYY-MM-DD`, or a relative window such as `7d`\n- The dashboard's Sessions summary shows the active five-hour billing block (local estimate from session logs), refreshed every minute\n- `sidekick daily`, `weekly`, `monthly`, and `sessions` report usage computed straight from session logs, so CLI-only users no longer see \"No historical data found\". Every provider with session data is read by default (the global `--provider` narrows to one); rows are bucketed by the time of each usage event on the local calendar (`--utc` for UTC), so a session crossing midnight is split across both days; weeks start on Monday. Options: `--since` / `--until` (ISO date, `YYYY-MM-DD`, or relative windows such as `30d`), `--breakdown` (per-model sub-rows), `--by-project`, `--csv`, `--no-cache`; the global `--json` prints the full report. Defaults: 30 days, 12 weeks, 12 calendar months, 30 days\n- `sidekick stats` points at `sidekick daily` when the history store is empty\n- `sidekick import [--since <time>]` folds finished sessions from every detected provider (or the global `--provider`) into `historical-data.json`, the store behind `stats`, `today`, and the VS Code History tab, using the same importer and store mutation as the extension. Files already imported, sessions already persisted by the live monitor, and files modified in the last minute are skipped; session logs are read without holding the store lock and the summaries are applied in one short locked write that re-checks the on-disk store\n- `sidekick statusline` writes `~/.config/sidekick/state.json` on every prompt (only when something changed) and the dashboard writes it on quota updates and billing-block ticks: a public, versioned (`schemaVersion: 1`) document with the active account, quota windows with freshness, context usage, session cost, and the active billing block, for tmux status bars, menu-bar apps, and scripts\n\n### Changed\n\n- Startup awaits bounded pricing-catalog hydration, so two runs of the same command price identically; a fresh cache is a local read and a refresh is capped by the catalog's 3 s timeout\n- Every token total (`stats`, `today`, the dashboard session panel, `dump`, `report`) includes cache reads and writes and is labelled \"Total (incl. cache)\"; cost figures carry their provenance\n- `sidekick today` looks up yesterday by local calendar day (the history store has always been keyed that way) and takes its peak-hours line from the shared schedule, so it agrees with `sidekick peak`\n- `sidekick quota` shows the age of a cached snapshot and only colours it as a warning when it is older than five minutes; `quota history` reads providers in parallel\n- The global `--json` flag applies to `dump` (same as `--format json`)\n- Commands set `process.exitCode` instead of calling `process.exit(1)` on errors, so piped output is never truncated\n- The status line no longer writes to the account registry on its hot path\n- `sidekick quota`, `quota --all`, and `mcp get_quota_status` resolve quota through the shared `resolveQuota()` precedence (fresh persisted sample, then session logs, then the provider API, then an older sample), so a fresh status-line sample is never outranked by an older session-derived value and `--all` no longer forces Codex API-first; `--refresh` asks the API first for every provider, not only Codex\n- Every quota table prints a `Source` row naming where the numbers came from (`cached status-line sample from \u2026 (3m ago)`, `local session logs`, `Anthropic usage API`, \u2026); JSON output adds `resolution`, `capturedSource`, `freshness`, and `ageMs`\n- `sidekick report` and the dashboard's report action read the session once through its provider reader and derive both the metrics and the transcript from those events, instead of replaying the session through a watcher and then parsing the file again; report metrics now come from the canonical event path (the same one `readSessionStats()` uses)\n- Codex session discovery, listings, and the local quota scan use the shared capped walker, so the dashboard's session poll and `sidekick quota` no longer enumerate and re-read the whole rollout history on every call\n- The dashboard detects new sessions by subscribing to the provider's session root (`fs.watch` with a 30 s catch-up poll) instead of walking the session corpus every 10 s; the followed session's own writes no longer trigger a lookup\n- `DashboardState.getMetrics()` returns the same object until the next mutation, and the dashboard memoises panel items and detail rendering on that identity (plus each panel's `viewVersion`), so key presses, scrolling, and toasts no longer rebuild every panel\n- Provider status polling is scoped to the active provider: status.claude.com for Claude Code, status.openai.com for Codex, nothing for OpenCode\n- `sidekick dump --list` and the multi-provider session picker read the bounded async preview index; `--list` prints enumeration diagnostics to stderr and shows the \"raise --limit\" footer only when more sessions exist beyond the limit\n- `sidekick stats` text mode: the Top Failing Tools block shows the last 7 and 30 days side by side with a trend arrow; `--json` output is unchanged\n\n### Fixed\n\n- `--offline` and `--output-file` given before the command are recognised by the command-token scan: `sidekick --offline stats` used to skip catalog hydration entirely and price from the static table, and `sidekick --offline statusline` fell off the fast path\n- `--output-file` writes plain text: chalk's colour level is reset when the redirect is installed, unless `FORCE_COLOR` is set\n- The dashboard's `state.json` keys quota by the sample's `providerId` when one is stamped\n\n## [0.25.0] - 2026-08-18\n\n### Changed\n\n- The CLI advances in lockstep with `sidekick-shared` 0.25.0 and retains its existing commands and synchronous compatibility surface\n\n## [0.24.5] - 2026-08-18\n\n### Added\n\n- `sidekick history` lists recent Codex user prompts across every workspace from `~/.codex/history.jsonl`, newest first, as an AGE / SESSION / PROMPT table sized to the terminal. `--limit <n>` bounds the count (default 20) and the underlying tail read scales with the limit, so large limits are not silently truncated. `--path <id-or-prefix>` resolves a full session id or unique prefix to its rollout transcript path \u2014 `less \"$(sidekick history --path 0198a3c2)\"` \u2014 and the global `--json` emits full ids and ISO timestamps. Codex-only for now; not to be confused with `sidekick quota history`\n- `sidekick dump --list` gains `--limit <n>` (default 50). The listing and the interactive session picker both read the shared session-preview index, which stats first and content-reads only the sessions actually shown \u2014 listing a project with a large session history no longer reads every file\n\n### Changed\n\n- `dump --list` prints provider-canonical session ids \u2014 for Codex, the bare session UUID rather than the `rollout-\u2026` file basename. The listed id now round-trips into `dump --session <id>` (the old basename never matched exact or prefix); scripts parsing `--list --json` should expect the new `id` form\n\n## [0.24.4] - 2026-07-25\n\n### Fixed\n\n- The dashboard loaded persisted project data exactly once at startup and never again, so tasks, notes, decisions, and plans written by the VS Code extension or a second terminal never appeared until the dashboard was restarted\n- Load and watcher failures were swallowed into empty catch blocks. A failed load was replaced with an all-zero object and both watcher error handlers were empty, producing a dashboard indistinguishable from a genuinely quiet project\n- `sidekick dashboard` without a TTY rendered Ink's \"Raw mode is not supported\" panel into the middle of a partial frame and exited 0, so callers read the failure as success. It now fails with a message naming which stream is not a TTY, suggests a command that works when piped, and exits 1\n- Mouse tracking escape sequences were written to stdout with no TTY check, polluting redirected output\n- A bare `sidekick` printed full help to stderr with exit 1, breaking `sidekick | less` and any script checking the exit code. It now writes to stdout and exits 0\n- `sidekick --help` and `sidekick --version` made a network request and created `~/.config/sidekick/accounts/` before printing anything, because the startup side effects ran at module scope\n- `sidekick --no-color` was rejected as an unknown option, even though chalk already honored it, `NO_COLOR`, and a non-TTY stdout\n- Printing help for a bare invocation ran before Commander parsed the argv, which skipped its validation too: `sidekick --provider bogus` and `sidekick --project` (missing its value) exited 0 with help instead of reporting the error. Help for a bare or flag-only invocation is now a root action handler, so `sidekick | less` still works without disarming the option checks, and `sidekick bogus` still reports an unknown command\n- Switching to a pending session was impossible from the Plans panel: it bound `s` with no condition, so the panel's handler fired whenever an item was selected, which on Plans is always. The Sessions panel shadowed the global session filter on its Mind Map tab the same way\n- When the item list shrank under the cursor \u2014 live event churn, or typing into the filter \u2014 the detail tab and scroll position jumped back to the top of the first tab\n- The detail tab bar could highlight a tab whose content was not being rendered\n- The detail pane could render empty beneath a \"\u25B2 (N more)\" indicator. The scroll offset survives a list shrinking under the cursor, so it can outlive the content it was measured against; it is now clamped to whatever content it lands on\n- On the splash screen, panel digits 1 and 2 did nothing while 3 through 8 entered the dashboard\n- Only the newest toast was rendered, so a quota alert landing next to a context compaction showed one message and silently dropped the other\n- `parseBlessedTags.test.tsx` had never run: the vitest include glob was `*.test.ts`, which does not match `.test.tsx`. That is 15 tests covering the tag parser every rendered string flows through\n- `vitest.config.ts` declared `define` nested under `test`, where Vitest ignores it, so the `__CLI_VERSION__` injection its comment describes was inert and the next test importing `cli.ts` or `StatusBar.tsx` would have failed on a `ReferenceError`\n- `sidekick extract -i --json` silently ignored `--json`; it is now rejected, and `extract -i` degrades to plain output when not attached to a terminal\n\n### Added\n\n- `R` refreshes persisted project data on demand, and data auto-refreshes every 15 seconds. The refresh is gated by a content fingerprint, so an unchanged project schedules no re-render at all. Plan progress is part of that fingerprint: a plan record is replaced in place and keeps its `createdAt` with no `completedAt` while it runs, so a timestamp-only signature could not see steps advancing and `R` would report \"Project data is up to date\" against a stale Plans panel\n- A status-bar badge for data health, covering load failures, watcher errors, in-flight refreshes, and staleness. A watcher error expires from the badge 60 seconds after the last failure, matching the watcher's own treatment of these errors as recoverable \u2014 it closes the handle and degrades to catch-up polling \u2014 so one transient hiccup cannot latch the badge for the life of the process and hide the staleness signal behind it\n- Toasts stack up to three\n- `R`, `p`, and `s` are listed in the help overlay; `p` and `s` were previously documented only in the README\n\n### Changed\n\n- The Plans panel's source filter moved from `s` to `S`, and the Sessions panel's mind-map node filter from `f` to `F`, so the reserved global session-switch and session-filter keys work from every panel\n- The pricing cache follows `SIDEKICK_CONFIG_DIR` rather than a hardcoded `~/.config/sidekick`\n\n### Removed\n\n- The dead ANSI mind-map renderer and its helpers, and the unused `getRandomPhraseColored()`\n\n## [0.24.3] - 2026-07-24\n\n### Fixed\n\n- Dashboard costs for Claude Sonnet 5 ran 50% high, billed at $3/$15 instead of its actual $2/$10. Sonnet 5 is the `balanced` tier for the Claude API and OpenCode providers, so this shifted most totals shown before the pricing catalog was fetched\n- Dashboard costs for GPT-5.6 Luna ran about 5\xD7 high until the pricing catalog was fetched, because Luna had no rate of its own and fell back to GPT-5.6 Sol's $5/$30 rather than its published $1/$6. GPT-5.5 Pro, GPT-5.4 Pro, and GPT-5.4 Nano shared the cause and are corrected too\n- Twelve more models drew their cost from a similar model's rate. Mini and nano tiers read far too expensive (GPT-5 Nano 25\xD7 high, GPT-4.1 Nano 20\xD7) and pro tiers far too cheap (GPT-5 Pro, GPT-5.2 Pro, o1-pro, o3-pro, and o3-deep-research all showed their base model's rate). GPT-5.3 Codex and o1-mini were on outdated rates\n- GPT-5.6 Luna sizes its context gauge from an explicit 1,050,000-token window, still superseded by the window Codex reports for your tier\n\n## [0.24.2] - 2026-07-24\n\n### Added\n\n- Context windows previously reported by a provider are loaded at startup and applied to historical views, so a Codex session shows the window its account tier actually gets rather than the model's published maximum. Local read, offline-safe, non-blocking\n- Context windows also hydrate from the LiteLLM catalog, so newly released models size correctly without a CLI update\n\n### Fixed\n\n- The context gauge read roughly eight times fuller than reality on Claude Sonnet 4.7, which resolved to a 128K window against its real 1M. Sonnet 4 was affected by the same cause\n\n## [0.24.1] - 2026-07-22\n\n### Changed\n\n- Session reads inherit the shared transcript provenance surface: entrypoint, meta/sidechain flags, original roles, cwd, and git branch flow through canonical transcripts\n\n## [0.24.0] - 2026-07-22\n\n### Changed\n\n- Session reads inherit the shared discriminated event contract, normalized usage pricing, canonical transcripts, and isolated observed-session collection surface\n- A provider-reported $0 session cost now displays as $0 rather than a catalog estimate\n\n## [0.23.1] - 2026-07-21\n\n### Security\n\n- Clipboard and URL-opening helpers spawn platform tools with argument arrays instead of interpolated shell strings\n\n### Fixed\n\n- **2026-07 review backlog (CLI portion)**: quota-failure text wraps instead of rendering one character per line, the `today` date filter includes today in UTC-negative timezones, mouse clicks land on the clicked row, and configured model IDs reach the inference clients instead of being squashed to `haiku`\n- Shared observed-session reads tolerate message-less summary/bookkeeping rows and retain unresolved top-level tool requests with stable fallback IDs\n\n### Changed\n\n- `sidekick quota` now exits non-zero when a requested provider's quota is unavailable (including `--all` and `--json` failure payloads), so scripts can detect failures\n- The deprecated `quota --tier` flag (part of the removed z.ai observed-traffic estimator) is no longer accepted\n\n## [0.23.0] - 2026-07-18\n\n### Added\n\n- **`sidekick statusline`** renders a warm, cache-only account/quota/burn footer without account bootstrap, pricing hydration, or quota network access\n- **Quick capture** with `tasks add`, `tasks done`, `note add`, and `decision add`, using the shared atomic merge writers\n- **`sidekick doctor` and `sidekick today`** provide cross-provider health diagnostics and a cache-only daily brief\n- **`sidekick mcp`** exposes seven read-only facts tools for quota, burn rate, context pressure, tasks, decisions, notes, and composed project context over stdio MCP\n- **Generic handoff deep links** through `handoff open --url-template`, with identifier-only placeholders and a no-open mode\n- Failure-history, quality trend, code-impact, per-model churn/cost, and compaction-ledger summaries in terminal views\n\n### Changed\n\n- The Plans pipeline is active again: live plans persist to the shared plan store and carry per-step time, token, tool, and cost analytics into the dashboard\n- Static readers use canonical symlink-aware project identity, including legacy-store fallback\n\n## [0.22.0] - 2026-07-02\n\n### Added\n\n- **Date filter mode now actually filters by date**: The dashboard's `[D]ate` filter previously fell through to plain substring matching. It now parses `today`, `yesterday`, relative windows (`12h`, `2d`, `1w`), ISO days (`YYYY-MM-DD`), and `>`/`<` prefixes (`<2d` = older than two days); unparseable expressions show the red filter error while leaving the list unfiltered, and the overlay shows a grammar hint while empty\n- **Mouse-capture toggle**: Press `M` in the dashboard (works on the splash screen too) or launch with `--no-mouse` to disable mouse tracking so terminal click-drag text selection and copy work again. The status bar shows `MOUSE OFF` while disabled; the interactive toggle persists to `cli-config.json`, the flag is per-run\n- **Scrollable help overlay**: `?` help now windows its content with `j`/`k` scrolling and \u25B2/\u25BC indicators, so nothing is clipped on short terminals\n- **Examples in `--help`**: The root command plus `quota`, `extract`, and `dump` append real invocation examples showcasing `quota --all`, `quota history`, `extract -i`, `dump --list`, and the global `--json` flag\n- **Strict option validation**: `--provider` (root, `quota`, `quota history`, `peak`), `report --theme`, `tasks --status`, and `quota --tier` now reject unknown values at parse time with the allowed choices, instead of silently coercing typos to a default. `quota history` keeps its legacy `claude-code`/`z.ai` aliases\n- **Confirmation before `account --remove`**: Both the Claude and Codex remove paths now print the resolved account and require an interactive y/N answer (default No). `-y`/`--yes` (or `--force`) skips the prompt; `--json` and non-TTY contexts require the flag and exit 1 otherwise \u2014 **unattended automation that removes accounts must add `--yes`**\n\n### Fixed\n\n- **`q` is typable in the filter box**: The quit key no longer swallows `q` while the filter overlay is open, so queries like `query` or `sqlite` work; `q` still closes the help/changelog/context-menu overlays and quits the dashboard otherwise\n- **Panel keybindings are reachable**: Panel-declared bindings now win over the shadowable global keys while their condition holds \u2014 the Sessions panel's Mind Map `f` (filter nodes) binding works when the Mind Map tab is active, falling back to the global session filter elsewhere. Reserved keys (`q ? / M j k g G h` and digits) can never be shadowed by a panel\n- **Overlays track terminal resize**: Filter, toast, context-menu, and changelog overlays reposition on resize and clamp their widths to narrow terminals; the splash `jump` hint reflects the real panel count instead of `1-5`; the Sessions summary tasks line no longer renders as `3/ completed`\n- **Detail pane wraps to the actual layout**: Word-wrap now derives from the live side-panel width (narrow/normal/wide-side/expanded) instead of assuming the default 26-column panel, fixing under-/over-wrapping in three of the four layout modes\n- **Overlay scroll clamps to content**: The `?` help and `V` changelog overlays no longer accumulate scroll past their last line \u2014 over-scrolling then reversing responds immediately, and the changelog overlay no longer shows a blank box when scrolled past the end\n\n### Changed\n\n- **Ctrl+C always quits the dashboard**, even while an overlay is open (previously it only closed the overlay)\n- **`V` (changelog) and `r` (report) are inactive on the splash screen**; `q`, `?`, `M`, and panel digits still work there\n\n## [0.21.6] - 2026-07-02\n\n### Added\n\n- **Codex reset credits in `sidekick quota`**: When Codex quota is fetched from the API (`--refresh`, or the API-first `--all` view), the Rate Limits output now includes a `Reset Credits: N available` line plus a per-credit `Expires` row (expiry timestamp and title) for each available reset grant\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.6**: Picks up `fetchCodexResetCreditsFromApi()` and the reset-credits snapshot on Codex quota state\n\n## [0.21.5] - 2026-06-30\n\n### Fixed\n\n- **`sidekick quota --all` no longer shows Codex at 0%**: Codex emits multiple rate-limit families per session (the aggregate plan quota plus per-model families like `codex_bengalfox`). A per-model family at 0% with a later reset window could mask the real plan quota in the local-data path; the aggregate family is now always preferred, so `--all` matches `--provider codex --refresh`. `quota --all` also fetches Codex API-first (with automatic local fallback), matching the live Claude/z.ai legs; the single-provider `quota --provider codex` stays local-by-default (live via `--refresh`)\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.5**: Picks up the aggregate Codex rate-limit selection\n\n## [0.21.4] - 2026-06-30\n\n### Fixed\n\n- **`sidekick quota` shows the logged-in account**: The account line now reflects the currently logged-in Claude/Codex account even after a native `claude /login` or `codex login`, instead of the stale saved registry pointer. The live Codex account is resolved once per invocation and reused across the fetch and the printed output\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.4**: Picks up the live-first active-account resolvers\n\n## [0.21.3] - 2026-06-23\n\n### Changed\n\n- **`sidekick quota` projects every provider**: Quota output is now rendered as a unified table with aligned `now` / `projected` / `resets` columns, and projected end-of-window utilization is shown for **all** providers (Claude, Codex, z.ai) \u2014 previously only Claude displayed a projection. A `\u2014` placeholder appears when a projection is unavailable, and utilization bars are clamped to 0\u2013100% so over-limit projections render cleanly. `sidekick quota --all` uses the same table for each provider section\n- **Bundled `sidekick-shared` 0.21.3**: Picks up the quota projection helpers and the bounded synchronous CLI probes\n\n### Security\n\n- **npm audit**: Bumped `esbuild` to `^0.28.1` and `vitest` to `^4.1.9` to clear reported dev-dependency advisories\n\n## [0.21.2] - 2026-06-22\n\n### Changed\n\n- **`sidekick quota --provider zai`** now renders authoritative z.ai plan utilization from z.ai's quota API (5-Hour / Weekly windows with real reset times) instead of estimating from observed OpenCode traffic, falling back to a cached snapshot when the API is unavailable. `sidekick quota --all` and `sidekick quota history --provider zai` use the same authoritative source\n- **`--tier lite|pro|max|auto`** is deprecated and no longer affects the displayed utilization\n\n## [0.21.1] - 2026-06-21\n\n### Added\n\n- **z.ai Coding Plan quota**: `sidekick quota --provider zai` derives and renders z.ai plan utilization from OpenCode traffic already on disk (5-Hour / Weekly windows with per-tier prompt budgets). `--tier lite|pro|max|auto` overrides the assumed plan tier (default `auto`). `sidekick quota --provider opencode` now auto-routes to z.ai quota when z.ai traffic is detected. `sidekick quota --all` includes the z.ai section when active\n- **z.ai quota history heatmap**: `sidekick quota history --provider zai` renders a 13-week z.ai utilization heatmap for the current workspace, alongside the existing Claude and Codex heatmaps (now also in `--all`)\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.1**: Picks up z.ai quota derivation and the OpenCode data directory resolution fix.\n\n### Limitations\n\n- z.ai quota is **estimated, not authoritative** \u2014 it reflects only the OpenCode traffic Sidekick observed on this machine/workspace (z.ai exposes no usage API) compared against provisional per-tier prompt budgets. z.ai is observed-only (no z.ai inference provider) and has no account management yet; with `--tier auto`, the tier is under-detected early in a cycle (use an explicit `--tier`); reset times are approximate unless a rate-limit error is trapped.\n\n## [0.21.0] - 2026-06-21\n\n### Added\n\n- **Account login**: `sidekick account --login` starts the provider-isolated login flow for Claude Max or Codex and saves the authenticated profile without disturbing the active account until finalization\n- **All-provider account view**: `sidekick account --provider all` lists Claude and Codex saved accounts together, including active state. JSON output returns provider-keyed account arrays and active ids\n- **Terminal account helpers**: `sidekick account --launcher <name>` creates opt-in launchers for the selected account, and `--auto-switch <pct|off>` persists the CLI auto-switch threshold preference\n- **Multi-provider quota output**: `sidekick quota --all` shows Claude and Codex quota state together \u2014 each provider degrades independently, so one provider's quota still prints even when the other is unavailable; `--all --json` emits a provider-keyed payload for automation\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.0**: Picks up Account Management 2.0 acquisition, switching, terminal sync, quota auto-switch, and account schema exports.\n\n## [0.20.0] - 2026-06-17\n\n### Added\n\n- **`sidekick extract`**: New one-shot command for pulling actionable assets out of recent Claude Code and Codex chats for exactly the current cwd. It extracts URLs, filesystem-validated file paths, commands the agent suggested for the user to run, and plan-mode plans. Output is grouped and colored by default, labels each item with its source agent, validates invalid `--type` and `--limit` values, preserves `inChat` and per-item provenance in `--json`, and offers `-i/--interactive` for a picker that opens URLs or copies selected paths, commands, and plans. `--provider claude-code` and `--provider codex` scope extraction to one agent; OpenCode is reported as unsupported for now\n\nThanks to [@B33pBeeps](https://github.com/B33pBeeps) (Juan Fourie) for contributing this feature in [#17](https://github.com/cesarandreslopez/sidekick-agent-hub/pull/17), adapted from his MIT-licensed [`trawl`](https://github.com/B33pBeeps/trawl) project.\n\n## [0.19.3] - 2026-06-17\n\n### Changed\n\n- **Bundled `sidekick-shared` projection contract**: The shared assistant-turn projection now exposes a v2 `timeline` array for interleaved reasoning, narration, and tool groups. This is a shared-library contract update for downstream consumers and does not change CLI behavior by itself\n\n## [0.19.2] - 2026-06-15\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.19.2**: The shared library gains a browser-safe assistant-turn projection module (`segmentAssistantTurn()`, `assistantTurnEventsFromSessionEvents()`, and mirrored Zod schemas) that segments an assistant turn into a compact Process + Answer shape, with Claude `Task` subagent refs surfaced without leaking prompt text \u2014 internal additions that don't change CLI behavior\n\n## [0.19.1] - 2026-06-09\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.19.1**: Model-ID pricing and context-window lookups (behind the dashboard's cost and context gauges) now tolerate padded or mixed-case IDs. The shared library also gains Zod boundary schemas, an `extractSessionEvents()` progress-unwrapping helper, and a `/schemas` subpath export for downstream consumers \u2014 internal additions that don't change CLI behavior\n\n## [0.19.0] - 2026-06-09\n\n### Added\n\n- **Claude Opus 4.8 & Fable 5 support**: The dashboard's context-window gauge and cost estimates recognize `claude-opus-4-8` and `claude-fable-5` (both 1M-token context; Opus 4.8: $5/$25 per MTok, Fable 5: $10/$50 per MTok) via the shared model catalog\n\n### Changed\n\n- **Codex account switching now swaps `~/.codex/auth.json`**: `sidekick account --provider codex --switch-to <id>` (and `--add`) activates the account by atomically swapping its backed-up credentials into the system `~/.codex/` home, mirroring the Claude switch pattern \u2014 codex terminals outside Sidekick pick up the switch. Profile directories become pure credential backups, with a one-time startup migration for installs created under the old `CODEX_HOME`-redirection model. The command surfaces swap warnings on add, switch, and remove: a running codex process that needs restarting, stale credentials, or OS-keyring credential storage that Sidekick cannot swap\n\n### Fixed\n\n- **Opus 4.6/4.7 cost over-estimation**: Dashed model IDs fell back to the Opus 4.0 pricing tier ($15/$75 instead of $5/$25), inflating estimated costs 3\xD7\n- **Haiku 4.5 unpriced under dashed IDs**: Costs for `claude-haiku-4-5-*` sessions could render as \"\u2014\" because no dashed static pricing key existed\n\n## [0.18.5] - 2026-06-04\n\n### Changed\n\n- **Consistent Codex transcripts**: `sidekick dashboard` and `sidekick report` now parse Codex sessions via `parseTranscriptFromEvents()`, matching the canonical `SessionEvent` pipeline used by the other providers\n- **Bundled `sidekick-shared` 0.18.5**: Picks up the new session context evidence snapshot API (`buildSessionContextSnapshot`, `readSessionContextSnapshot`, `SessionContextSnapshot` and related types) and the Codex session evidence gap closures \u2014 `system` audit events, normalized `token_count` rate limits, per-file `apply_patch` expansion, tool-emission dedupe, MCP server attribution, and the new `ProviderReaderSessionWatcher`\n\n## [0.18.4] - 2026-05-27\n\n### Added\n\n- **`sidekick peak --provider <id>`**: New flag gates peak-hours output on the session provider. When the resolved provider is not `claude-code`, the command prints a \"not applicable\" message instead of calling the upstream endpoint\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.4**: Picks up `scopePeakHoursToSessionProvider()`, `isClaudeCodeSessionProvider()`, `createPeakHoursNotApplicableState()` for peak-hours scoping, the improved Codex quota snapshot selection logic (`isPreferredQuotaHit`, `findAccountRolloutFiles`, `shouldKeepExistingSnapshot`), and the `notApplicable` field on `PeakHoursState`\n\n## [0.18.3] - 2026-05-19\n\n### Added\n\n- **`sidekick quota history`**: New subcommand that renders a 13-week GitHub-contributions-style heatmap of quota utilization for the current workspace. Flags: `--weeks <n>` (1-26, default 13), `--provider claude|codex` (default both), `--workspace <path>` (default cwd). Bucketed glyphs (`\xB7 \u2591 \u2592 \u2593 \u2588`) are color-coded by utilization band (\u22640 / <25 / <50 / <75 / \u226575), with per-provider rows and a peak / avg / unavailable-days / samples footer. Days that hit `available: false` render as a red `\xD7`. With `--json`, emits a `{ workspaceId, weeks, providers: { claude?, codex? }, generatedAt }` payload \u2014 the same shape consumed by the VS Code dashboard\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.3**: Picks up the new per-workspace quota history surface (`appendQuotaHistorySample`, `readQuotaHistoryRange`, `readQuotaHistoryDailyBuckets`, `pruneQuotaHistory`, `getWorkspaceIdFromPath`) and the optional `workspaceId` / `appendHistorySample` hooks on `CodexQuotaWatcher`\n\n## [0.18.2] - 2026-05-19\n\n### Added\n\n- **`sidekick quota --refresh`**: New flag on the `quota` command that, for Codex, explicitly refreshes from the ChatGPT usage API before falling back to local rollout data and cached snapshots. Without the flag, the Codex quota path stays fully local and makes no upstream network call\n\n### Changed\n\n- **Codex quota is local-only by default**: `sidekick quota --provider codex` now delegates to the new `resolveCodexQuota` orchestrator in `sidekick-shared`. It checks the current workspace's most recent rollout, then recent account-level rollouts under `CODEX_HOME/sessions`, then the active account's cached snapshot \u2014 no upstream network call unless `--refresh` is passed. Failure output continues to include structured `failureKind` / `httpStatus` / `retryAfterMs` fields under `--json`\n- **Bundled `sidekick-shared` 0.18.2**: Picks up the new Codex quota orchestrator (`resolveCodexQuota`, `resolveCodexQuotaFromLocalSources`, `readLatestCodexQuotaFromRollouts`, `fetchCodexQuotaFromApi`), the relaxed `CodexRateLimits` shape (nullable `resets_at` / `window_minutes`), the rate-limit-only `token_count` event emission in `JsonlSessionWatcher`, and `state_N.sqlite` discovery in `CodexDatabase` + provider auto-detect\n\n## [0.18.1] - 2026-05-08\n\n### Changed\n\n- **Shared dashboard formatting**: terminal dashboard `fmtNum()` and `formatDuration()` now delegate to `formatTokenCount()` and `formatDurationMs()` from `sidekick-shared`, keeping the existing CLI surface (uppercase `K`/`M` suffix, compact `1m5s` style) while removing forked rounding logic\n\n## [0.18.0] - 2026-05-08\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.0**: Picks up the new provider-aware quota orchestration surface \u2014 `MultiProviderQuotaService`, `CodexQuotaWatcher`, `getActiveAccountStatus()`, `extractToolCall()`, cost-provenance helpers (`calculateCostWithProvenance`, `mergeCostSources`), and model display helpers (`shortModelName`, `getModelDisplayInfo`, `compareModelIds`, `sortModelIds`). `parseModelId()` also now recognizes legacy Claude IDs such as `claude-3-opus-20240229` and `claude-3-5-sonnet-20241022`\n- **No CLI runtime changes**: This release ships the shared library upgrade for downstream tooling alignment; `sidekick quota`, `sidekick status`, and the live dashboard keep using the existing polling path. Wiring the new orchestrator into the CLI will land in a follow-up release\n\n## [0.17.7] - 2026-04-28\n\n### Fixed\n\n- **Quota snapshot write race**: Updated the bundled `sidekick-shared` snapshot writer so concurrent `sidekick quota` / Codex session updates no longer collide on `quota-snapshots.json.tmp` or throw `ENOENT`. Failed writes now also clean up their partial temp files instead of leaving orphans in `~/.config/sidekick/`\n\n## [0.17.6] - 2026-04-19\n\n### Added\n\n- **`sidekick peak` command**: One-shot check for Claude's current peak-hours state \u2014 weekdays 13:00\u201319:00 UTC, when session limits drain faster on Free/Pro/Max/Team subscriptions. Prints a color-coded status block with a countdown to the next transition. Data comes from the public `promoclock.co/api/status` endpoint (third-party, unaffiliated with Anthropic) with a graceful fallback when unreachable. `--json` emits the full raw state\n- **Peak-hours block in `sidekick status`**: When the active provider is `claude-code`, the Claude + OpenAI health blocks are now followed by a **Claude Peak Hours** block (off-peak or in-peak, with countdown). Gated on the provider so OpenCode / Codex users don't trigger an unnecessary third-party fetch. `--json` output includes the new `peak` field\n- **Peak-hours summary in `sidekick quota`**: Claude subscription quota output now shows a **Peak** line under the 5-hour / 7-day bars \u2014 green dot off-peak, orange dot during an active peak, with a countdown to the next transition. `--json` output includes the new `peak` field\n\n## [0.17.5] - 2026-04-18\n\n### Added\n\n- **Default account bootstrap at CLI startup**: The CLI now calls `ensureDefaultAccounts()` from `sidekick-shared` at module load and awaits the result inside a Commander `preAction` hook, so the first real subcommand blocks briefly on the bootstrap while `--version` and `--help` stay instant. When a system Claude Code or Codex credential exists and no saved account is active for that provider yet, the CLI registers it as \"Default\" \u2014 `sidekick quota`, `sidekick account`, and `sidekick stats` now reflect the active account on first run without requiring an explicit `sidekick account --add` first. Idempotent, never overwrites manually saved accounts, and all errors are swallowed so startup is never blocked\n\nThanks to [@B33pBeeps](https://github.com/B33pBeeps) (Juan Fourie) for contributing this feature in [#16](https://github.com/cesarandreslopez/sidekick-agent-hub/pull/16).\n\n## [0.17.4] - 2026-04-17\n\n### Changed\n\n- **Pricing hydration import migrated to `sidekick-shared/node`**: `cli.ts` now imports `hydratePricingCatalog` from the new Node-only subpath and keeps `detectProvider` on the package root. Runtime behavior is unchanged; the split makes the CLI's import surface self-documenting (hydration is explicitly a Node API) and aligns the CLI with the shared library's new versioned public API contract\n\n## [0.17.3] - 2026-04-17\n\n### Changed\n\n- **Version sync with the VS Code extension**: Republished to keep CLI, extension, and shared-library versions aligned after a cosmetic changelog fix in 0.17.3. No CLI code changes \u2014 functionally identical to 0.17.2\n\n## [0.17.2] - 2026-04-17\n\n### Added\n\n- **LiteLLM pricing hydration on startup**: The CLI now fetches the LiteLLM pricing catalog on startup and caches to `~/.config/sidekick/pricing-catalog.json` with a 24-hour TTL, 3s timeout, and stale-cache fallback \u2014 new model prices are picked up without a CLI upgrade\n- **Expanded pricing coverage**: GPT-4o, GPT-4.1, GPT-5.x, o1, o3, and o3-mini families are now priced alongside the existing Claude entries\n- **Real-dollar Codex / Claude Code costs**: `EventAggregator` computes cost from the pricing table when the session provider doesn't report one, so `sidekick` live dashboards now show actual dollars for Codex and Claude Code sessions\n- **`stats` footer lists unpriced models**: `sidekick stats` prints any models encountered with no pricing entry so missing coverage is visible\n\n### Fixed\n\n- **Context-gauge % wrong for Opus 4.7 (1M) and other new models**: The dashboard's context gauge was dividing by 200K for Claude Opus 4.7 (native 1M), inflating the displayed %. The shared model \u2192 context-window map now includes Opus/Sonnet 4.7 (1M), GPT-5.4 (1.05M), GPT-5.3-Codex (400K), and GPT-5.3-Codex-Spark (128K). Claude Code's `[1m]` suffix is now also honored as an explicit 1M marker\n- **Silent Sonnet-priced fallback for unknown models**: Codex, GPT-5.x, and o-series rows were being rendered at Sonnet rates. Unknown-model rows now render as `\u2014` in yellow instead of inventing a dollar figure\n\n### Changed\n\n- **`historical-data.json` schema v2**: reads `priced` flag and `unpricedModelIds` from records written by the latest VS Code extension; v1 records still read correctly\n\n## [0.17.1] - 2026-04-13\n\n### Fixed\n\n- **Codex multi-home session discovery**: Provider detection now scans all candidate Codex home directories, fixing missed sessions when the managed profile home is empty but the system `~/.codex/` has activity\n\n## [0.17.0] - 2026-04-13\n\n### Added\n\n- **Multi-provider account management**: `sidekick account` now supports `--provider codex` for Codex profile management alongside Claude Code accounts\n- **Codex account lifecycle**: `--add` prepares a profile and spawns `codex login`; `--switch-to` and `--remove` accept email, label, or profile ID\n- **Quota snapshot fallback**: `sidekick quota` for Codex shows cached rate-limit snapshots when no active session exists, with \"cached from\" timestamp\n\n### Fixed\n\n- **Email normalization**: Claude account lookup normalizes email case for reliable matching\n\n## [0.16.1] - 2026-03-27\n\n### Fixed\n\n- **Dashboard provider status scoping**: The TUI now shows degraded-service notices only for the monitored provider \u2014 Claude for Claude Code sessions, OpenAI for Codex sessions, and no status banner for OpenCode\n\n## [0.16.0] - 2026-03-23\n\n### Changed\n\n- **Consistent cost formatting**: All cost displays (`stats`, `context`, Sessions panel, narrative prompt) now use shared `formatCost()` with intelligent decimal precision (4 places for < $0.01, 2 otherwise)\n- **QuotaService**: Rewritten to wrap shared `QuotaPoller` with exponential backoff instead of manual polling loop\n- **modelContext**: Now re-exports `getModelInfo` from shared library alongside `getContextWindowSize`\n\n## [0.15.2] - 2026-03-18\n\n### Fixed\n\n- **CLI help descriptions**: Updated `quota` and `status` command descriptions to reflect provider-aware behavior\n- **`sidekick quota --provider`**: Added local `--provider` option so `sidekick quota --provider codex` works naturally\n\n## [0.15.0] - 2026-03-18\n\n### Added\n\n- **OpenAI status page monitoring**: CLI dashboard now shows OpenAI API status alongside Claude API status\n- **Codex rate limits in dashboard**: Sessions panel displays Codex rate-limit data with \"Rate Limits\" header instead of \"Quota\"\n- **Provider-aware `sidekick quota` command**: Detects active provider and shows Codex rate limits, Claude subscription quota, or an informational message for OpenCode\n\n### Fixed\n\n- **QuotaService polling for Codex**: Dashboard no longer starts Claude OAuth quota polling when the active provider is Codex\n\n## [0.14.2] - 2026-03-16\n\n### Fixed\n\n- **Quota polling interval**: Reduced quota refresh from every 30 seconds to every 5 minutes to avoid unnecessary API calls\n- **SessionsPanel `detailWidth()` call**: Removed unused parameter from `detailWidth()` in the Sessions panel quota rendering\n\n## [0.14.1] - 2026-03-14\n\n### Fixed\n\n- **Per-model context window sizes**: Dashboard context gauge now shows correct utilization for Claude Opus 4.6 (1M context) and other models with non-200K windows\n\n### Changed\n\n- **Shared model context lookup**: CLI dashboard now uses the centralized `getModelContextWindowSize()` from `sidekick-shared` instead of a local duplicate map\n\n## [0.14.0] - 2026-03-12\n\n### Added\n\n- **`sidekick account` Command**: Manage Claude Code accounts from the terminal \u2014 list saved accounts, add the current account with an optional label, switch to the next or a specific account, and remove accounts. Supports `--json` output for scripting\n- **Quota Account Label**: `sidekick quota` now shows the active account email and label above the quota bars when multi-account is enabled\n- **macOS Keychain Support**: `sidekick account` and `sidekick quota` now read and write credentials via the system Keychain on macOS, fixing account switching and quota checks on Mac\n\n## [0.13.8] - 2026-03-12\n\n### Changed\n\n- **Structured quota failure output**: `sidekick quota` now renders consistent auth, rate-limit, server, network, and unexpected-failure copy from shared quota failure descriptors while preserving `--json` machine-readable output\n- **Dashboard unavailable quota rendering**: The Sessions panel now shows Claude Code quota failures inline instead of hiding the quota section whenever subscription data is unavailable\n- **Quota transition toasts**: The Ink dashboard now fires low-noise toast notifications only when Claude Code quota failure state changes, avoiding repeated alerts every polling interval\n\n## [0.13.7] - 2026-03-11\n\n### Changed\n\n- **npm README sync**: Updated the published CLI package README to reflect current OpenCode monitoring behavior, platform-specific data directories, and the `sqlite3` runtime requirement\n- **README badge cleanup**: Removed the Ask DeepWiki badge from the published CLI package README; the repo root README still keeps it\n\n## [0.13.6] - 2026-03-11\n\n### Changed\n\n- **Refreshed CLI Dashboard Wordmark**: Updated the dashboard wordmark/header styling for a cleaner splash and dashboard identity\n\n### Fixed\n\n- **OpenCode dashboard startup**: OpenCode DB-backed session discovery now resolves projects by worktree, sandboxes, and session directory instead of quietly behaving like no session exists\n- **OpenCode runtime notices**: The CLI now prints an OpenCode-only actionable notice when `opencode.db` exists but `sqlite3` is missing, blocked, or otherwise unusable in the current shell environment\n\n## [0.13.5] - 2026-03-10\n\n### Added\n\n- **`sidekick status` Command**: One-shot Claude API status check with color-coded text output and `--json` mode\n- **Dashboard Status Banner**: Status bar shows a colored `\u25CF API minor/major/critical` indicator when Claude is degraded; Sessions panel Summary tab shows an \"API Status\" section with affected components and active incident details. Polls every 60s\n\n## [0.13.4] - 2026-03-08\n\n### Fixed\n\n- **Onboarding Phrase Spam**: Splash screen and detail pane motivational phrases memoized \u2014 no longer flicker every render tick (fixes [#13](https://github.com/cesarandreslopez/sidekick-agent-hub/issues/13))\n\n### Changed\n\n- **Simplified Logo**: Replaced 6-line ASCII robot art with compact text header in splash, help, and changelog overlays\n- **Removed Dead Code**: Removed unused `getSplashContent()` and `HELP_HEADER` exports from branding module\n\n## [0.13.3] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.2] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.1] - 2026-03-04\n\n### Added\n\n- **`sidekick quota` Command**: One-shot subscription quota check showing 5-hour and 7-day utilization with color-coded progress bars and reset countdowns \u2014 supports `--json` for machine-readable output\n- **Quota Projections**: Elapsed-time projections shown in `sidekick quota` output and TUI dashboard quota section \u2014 displays projected end-of-window utilization next to current value (e.g., `40% \u2192 100%`), included in `--json` output as `projectedFiveHour` / `projectedSevenDay`\n\n## [0.13.0] - 2026-03-03\n\n_No CLI-specific changes in this release._\n\n## [0.12.10] - 2026-03-01\n\n### Added\n\n- **Events Panel** (key 7): Scrollable live event stream with colored type badges (`[USR]`, `[AST]`, `[TOOL]`, `[RES]`), timestamps, and keyword-highlighted summaries; detail tabs for full event JSON and surrounding context\n- **Charts Panel** (key 8): Tool frequency horizontal bars, event type distribution, 60-minute activity heatmap using `\u2591\u2592\u2593\u2588` intensity characters, and pattern analysis with frequency bars and template text\n- **Multi-Mode Filter**: `/` filter overlay now supports four modes \u2014 substring, fuzzy, regex, and date range \u2014 Tab cycles modes, regex mode shows red validation errors\n- **Search Term Highlighting**: Active filter terms highlighted in blue within side list items\n- **Timeline Keyword Coloring**: Event summaries in the Sessions panel Timeline tab now use semantic keyword coloring \u2014 errors red, success green, tool names cyan, file paths magenta\n\n### Removed\n\n- **Search Panel**: Removed redundant Search panel (previously key 7) \u2014 the `/` filter with multi-mode support serves the same purpose\n\n## [0.12.9] - 2026-02-28\n\n### Added\n\n- **Standalone Data Commands**: `sidekick tasks`, `sidekick decisions`, `sidekick notes`, `sidekick stats`, `sidekick handoff` for accessing project data without launching the TUI\n- **`sidekick search <query>`**: Cross-session full-text search from the terminal\n- **`sidekick context`**: Composite output of tasks, decisions, notes, and handoff for piping into other tools\n- **`--list` flag on `sidekick dump`**: Discover available session IDs before requiring `--session <id>`\n- **Search Panel**: Search panel (panel 7) wired into the TUI dashboard\n\n### Changed\n\n- **`taskMerger` utility**: Duplicate `mergeTasks` logic extracted into shared `taskMerger` utility\n- **Model constants**: Hardcoded model IDs extracted to named constants\n\n### Fixed\n\n- **`convention` icon**: Notes panel icon replaced with valid `tip` type\n- **Linux clipboard**: Now supports Wayland (`wl-copy`) and `xsel` fallbacks, with error messages instead of silent failure\n- **`provider.dispose()`**: Added to `dump` and `report` commands (prevents SQLite connection leaks)\n\n## [0.12.8] - 2026-02-28\n\n### Changed\n\n- **Dashboard UI/UX Polish**: Visual overhaul for better hierarchy, consistency, and readability\n - Splash screen and help overlay now display the robot ASCII logo\n - Toast notifications show severity icons (\u2718 error, \u26A0 warning, \u25CF info) with inner padding\n - Focused pane uses double-border for clear focus indication\n - Section dividers (`\u2500\u2500 Title \u2500\u2500\u2500\u2500`) replace bare bold headers in summary, agents, and context attribution\n - Tab bar: active tab underlined in magenta, inactive tabs dimmed, bracket syntax removed\n - Status bar: segmented layout with `\u2502` separators; keys bold, labels dim\n - Summary metrics condensed: elapsed/events/compactions on one line, tokens on one line with cache rate and cost\n - Sparklines display peak metadata annotations\n - Progress bars use blessed color tags for consistent coloring\n - Help overlay uses dot-leader alignment for all keybinding rows\n - Empty state hints per panel (e.g. \"Tasks appear as your agent works.\")\n - Session picker groups sessions by provider with section headers when multiple providers are present\n\n## [0.12.7] - 2026-02-27\n\n### Added\n\n- **HTML Session Report**: `sidekick report` command generates a self-contained HTML report and opens it in the default browser\n - Options: `--session`, `--output`, `--theme` (dark/light), `--no-open`, `--no-thinking`\n - TUI Dashboard: press `r` to generate and open an HTML report for the current session\n\n## [0.12.6] - 2026-02-26\n\n### Added\n\n- **Session Dump Command**: `sidekick dump` exports session data in text, markdown, or JSON format with `--format`, `--width`, and `--expand` options\n- **Plans Panel Re-enabled**: Plans panel restored in CLI dashboard with plan file discovery from `~/.claude/plans/`\n- **Enhanced Status Bar**: Session info display improved with richer metadata\n\n### Fixed\n\n- **Old snapshot format migration**: Restoring pre-0.12.3 session snapshots no longer shows empty timeline entries\n\n### Changed\n\n- **Phrase library moved to shared**: CLI-specific phrase formatting kept local, all phrase content now from `sidekick-shared`\n\n## [0.12.5] - 2026-02-24\n\n### Fixed\n\n- **Update check too slow to notice new versions**: Reduced npm registry cache TTL from 24 hours to 4 hours so upgrade notices appear sooner after a new release\n\n## [0.12.4] - 2026-02-24\n\n### Fixed\n\n- **Session crash on upgrade**: Fixed `d.timestamp.getTime is not a function` error when restoring tool call data from session snapshots \u2014 `Date` objects were serialized to strings by JSON but not rehydrated on restore, causing the session monitor to crash on first run after upgrading from 0.12.2 to 0.12.3\n\n## [0.12.3] - 2026-02-24\n\n### Added\n\n- **Latest-node indicator**: The most recently added node in tree and boxed mind map views is now marked with a yellow indicator\n- **Plan analytics in mind map**: Tree and boxed views now display plan progress and per-step metrics\n - Tree view: plan header shows completion stats; steps show complexity, duration, tokens, tool calls, and errors in metadata brackets\n - Box view: progress bar with completion percentage; steps show right-aligned metrics; subtitle shows step count and total duration\n- **Cross-provider plan extraction**: Shared `PlanExtractor` now handles Claude Code (EnterPlanMode/ExitPlanMode) and OpenCode (`<proposed_plan>` XML) plans \u2014 previously only Codex plans were shown\n- **Enriched plan data model**: Plan steps include duration, token count, tool call count, and error messages\n- **Phase-grouped plan display**: When a plan has phase structure, tree and boxed views group steps under phase headers with context lines from the original plan markdown\n- **Node type filter**: Press `f` on the Mind Map tab to cycle through node type filters (file, tool, task, subagent, command, plan, knowledge-note) \u2014 non-matching sections render dimmed in grey\n\n### Fixed\n\n- **Kanban board regression**: Subagent and plan-step tasks now correctly appear in the kanban board\n\n### Changed\n\n- **Plans panel temporarily disabled**: The Plans panel in the CLI dashboard is disabled until plan-mode event capture is reliably working end-to-end. Plan nodes in the mind map remain active.\n- `DashboardState` now delegates to shared `EventAggregator` instead of maintaining its own aggregation logic\n\n## [0.12.2] - 2026-02-23\n\n### Added\n\n- **Update notifications**: The dashboard now checks the npm registry for newer versions on startup and shows a yellow banner in the status bar when an update is available (e.g., `v0.13.0 available \u2014 npm i -g sidekick-agent-hub`). Results are cached for 24 hours to avoid repeated network requests.\n\n## [0.12.1] - 2026-02-23\n\n### Fixed\n\n- **VS Code integration**: Fixed exit code 127 when the extension launches the CLI dashboard on systems using nvm or volta (node binary not found when shell init is bypassed)\n\n## [0.12.0] - 2026-02-22\n\n### Added\n\n- **\"Open CLI Dashboard\" VS Code Integration**: New VS Code command `Sidekick: Open CLI Dashboard` launches the TUI dashboard in an integrated terminal\n - Install the CLI with `npm install -g sidekick-agent-hub`\n\n## [0.11.0] - 2026-02-19\n\n### Added\n\n- **Initial Release**: Full-screen TUI dashboard for monitoring agent sessions from the terminal\n - Ink-based terminal UI with panels for sessions, tasks, kanban, mind map, notes, decisions, search, files, and git diff\n - Multi-provider support: auto-detects Claude Code, OpenCode, and Codex sessions\n - Reads from `~/.config/sidekick/` \u2014 the same data files the VS Code extension writes\n - Usage: `sidekick dashboard [--project <path>] [--provider <id>]`\n"});function qxe(e,t){if(!t)return null;if(e==="regex"){try{new RegExp(t)}catch(n){return n instanceof Error?n.message:"Invalid regex"}return null}if(e==="date"){let n=mF(t);return"error"in n?n.error:null}return null}function Zxe(e,t){switch(t.type){case"SWITCH_PANEL":return{...e,activePanelIndex:t.index,selectedItemIndex:0,detailTabIndex:0,filterString:"",filterMode:"substring",filterError:null,focusTarget:"side",overlay:null,detailScrollOffset:0};case"SELECT_ITEM":return{...e,selectedItemIndex:t.index,detailTabIndex:0,detailScrollOffset:0};case"CLAMP_SELECTION":return{...e,selectedItemIndex:t.index};case"SET_DETAIL_TAB":return{...e,detailTabIndex:t.index,detailScrollOffset:0};case"CYCLE_DETAIL_TAB":{if(t.tabCount<=1)return e;let n=(e.detailTabIndex+t.direction+t.tabCount)%t.tabCount;return{...e,detailTabIndex:n,detailScrollOffset:0}}case"CYCLE_LAYOUT":{let n=["normal","expanded","wide-side"],r=n.indexOf(e.layoutMode),o=n[(r+1)%n.length];return{...e,layoutMode:o,focusTarget:o==="expanded"?"detail":e.focusTarget}}case"TOGGLE_FOCUS":return{...e,focusTarget:e.focusTarget==="side"?"detail":"side"};case"SET_FOCUS":return{...e,focusTarget:t.target};case"SET_OVERLAY":return{...e,overlay:t.overlay,contextMenuIndex:0,overlayScrollOffset:0};case"SET_FILTER":return{...e,filterString:t.value,filterError:qxe(e.filterMode,t.value)};case"CYCLE_FILTER_MODE":{let n=["substring","fuzzy","regex","date"],r=n.indexOf(e.filterMode),o=n[(r+1)%n.length];return{...e,filterMode:o,filterError:qxe(o,e.filterString)}}case"SET_FILTER_ERROR":return{...e,filterError:t.error};case"SET_SESSION_FILTER":return{...e,sessionFilter:t.filter};case"SCROLL_DETAIL":return{...e,detailScrollOffset:t.offset};case"SCROLL_DETAIL_DELTA":{let n=ux(t.totalLines,t.viewportHeight),r=Math.max(0,Math.min(e.detailScrollOffset+t.delta,n));return{...e,detailScrollOffset:r}}case"ADD_TOAST":return{...e,toasts:[...e.toasts,t.toast]};case"REMOVE_TOAST":return{...e,toasts:e.toasts.filter(n=>n.id!==t.id)};case"FIRST_EVENT":return{...e,hasReceivedEvents:!0,sessionFilter:t.sessionPrefix?{sessionPrefix:t.sessionPrefix,label:"\u25CF active session"}:null};case"CONTEXT_MENU_NAV":{if(t.itemCount===0)return e;let n=(e.contextMenuIndex+t.delta+t.itemCount)%t.itemCount;return{...e,contextMenuIndex:n}}case"CONTEXT_MENU_SELECT":return{...e,overlay:null};case"SCROLL_SIDE":{if(t.itemCount===0)return e;let n=Math.max(0,Math.min(e.selectedItemIndex+t.delta,t.itemCount-1));return{...e,selectedItemIndex:n,detailTabIndex:0,detailScrollOffset:0}}case"OVERLAY_SCROLL":return{...e,overlayScrollOffset:Math.max(0,e.overlayScrollOffset+t.delta)};case"CLAMP_OVERLAY_SCROLL":return{...e,overlayScrollOffset:Math.min(e.overlayScrollOffset,Math.max(0,t.maxOffset))};case"TOGGLE_MOUSE":return{...e,mouseEnabled:!e.mouseEnabled};case"TICK":return{...e,renderTick:e.renderTick+1};default:return e}}var Kxe,Yxe=B(()=>{"use strict";hF();u1();Kxe={activePanelIndex:0,selectedItemIndex:0,detailTabIndex:0,layoutMode:"normal",focusTarget:"side",overlay:null,filterString:"",filterMode:"substring",filterError:null,sessionFilter:null,detailScrollOffset:0,toasts:[],hasReceivedEvents:!1,contextMenuIndex:0,overlayScrollOffset:0,renderTick:0,mouseEnabled:!0}});function Vxe(e,t,n){let{state:r,dispatch:o,exit:i,panels:s,panel:c,selectedItem:l,contextActions:p,currentItemCount:h,clampedSelection:g,sideScroll:v,detailTabCount:E,detailLineCount:I,detailViewportHeight:x,addToast:_,toggleSessionFilter:T,onMouseSettingChange:M,onRefresh:$,onGenerateReport:z,onTogglePin:U,isPinned:se,pendingSessionPath:H,onSessionSwitch:ie,accountViews:oe,onAccountSwitch:W,onAccountUndo:de}=n;if(t.ctrl&&e==="c"){i();return}if(r.overlay==="filter"){if(t.escape){o({type:"SET_FILTER",value:""}),o({type:"SET_OVERLAY",overlay:null});return}if(t.return){o({type:"SET_OVERLAY",overlay:null});return}if(t.tab){o({type:"CYCLE_FILTER_MODE"});return}if(t.backspace||t.delete){o({type:"SET_FILTER",value:r.filterString.slice(0,-1)});return}if(e&&!t.ctrl&&!t.meta){o({type:"SET_FILTER",value:r.filterString+e});return}return}if(r.overlay==="context-menu"){if(t.escape||e==="q"){o({type:"SET_OVERLAY",overlay:null});return}if(e==="j"||t.downArrow){o({type:"CONTEXT_MENU_NAV",delta:1,itemCount:p.length});return}if(e==="k"||t.upArrow){o({type:"CONTEXT_MENU_NAV",delta:-1,itemCount:p.length});return}if(t.return){let be=p[r.contextMenuIndex];if(be&&l){let he=be.handler(l);typeof he=="string"&&_(he,he.toLowerCase().includes("fail")||he.toLowerCase().includes("unavailable")?"error":"info"),o({type:"CONTEXT_MENU_SELECT"})}return}let _e=p.find(be=>be.key===e);if(_e&&l){let be=_e.handler(l);typeof be=="string"&&_(be,be.toLowerCase().includes("fail")||be.toLowerCase().includes("unavailable")?"error":"info"),o({type:"CONTEXT_MENU_SELECT"})}return}if(r.overlay==="accounts"){let _e=oe??[];if(t.escape||e==="q"||e==="A"){o({type:"SET_OVERLAY",overlay:null});return}if(e==="j"||t.downArrow){o({type:"CONTEXT_MENU_NAV",delta:1,itemCount:Math.max(1,_e.length)});return}if(e==="k"||t.upArrow){o({type:"CONTEXT_MENU_NAV",delta:-1,itemCount:Math.max(1,_e.length)});return}if(t.return){let be=_e[r.contextMenuIndex];be&&W?.(be),o({type:"SET_OVERLAY",overlay:null});return}if(e==="u"){de?.(),o({type:"SET_OVERLAY",overlay:null});return}e==="a"?_("Run: sidekick accounts add","info"):e==="l"?_("Run: sidekick accounts login <name>","info"):e==="s"&&_("Run: sidekick accounts shell <name>","info");return}if(r.overlay==="help"){t.escape||e==="?"||e==="q"?o({type:"SET_OVERLAY",overlay:null}):e==="j"||t.downArrow?o({type:"OVERLAY_SCROLL",delta:1}):(e==="k"||t.upArrow)&&o({type:"OVERLAY_SCROLL",delta:-1});return}if(r.overlay==="changelog"){t.escape||e==="V"||e==="q"?o({type:"SET_OVERLAY",overlay:null}):e==="j"||t.downArrow?o({type:"OVERLAY_SCROLL",delta:1}):(e==="k"||t.upArrow)&&o({type:"OVERLAY_SCROLL",delta:-1});return}if(e==="q"){i();return}if(t.escape){if(r.filterString){o({type:"SET_FILTER",value:""});return}if(r.focusTarget==="detail"){o({type:"SET_FOCUS",target:"side"});return}return}if(e==="?"){o({type:"SET_OVERLAY",overlay:"help"});return}if(e==="A"){o({type:"SET_OVERLAY",overlay:"accounts"});let _e=(oe??[]).findIndex(be=>be.isActive);_e>0&&o({type:"CONTEXT_MENU_NAV",delta:_e,itemCount:Math.max(1,(oe??[]).length)});return}if(e==="M"){let _e=!r.mouseEnabled;o({type:"TOGGLE_MOUSE"}),_(_e?"Mouse capture on":"Mouse capture off \u2014 terminal text selection enabled","info"),M?.(_e);return}if(e==="R"){if(!$)return;$(),_("Refreshing project data\u2026","info");return}if(e==="s"&&H&&ie){ie(H);return}let ae=parseInt(e,10);if(ae>=1&&ae<=s.length){r.hasReceivedEvents||o({type:"FIRST_EVENT",sessionPrefix:""}),s[r.activePanelIndex]?.onDeactivate?.(),o({type:"SWITCH_PANEL",index:ae-1}),s[ae-1]?.onActivate?.();return}if(r.hasReceivedEvents){if(t.tab){o({type:"TOGGLE_FOCUS"});return}if(e==="/"){o({type:"SET_OVERLAY",overlay:"filter"});return}if(e&&!nXe.has(e)){let be=(c.getKeybindings?.()||[]).find(he=>he.keys.includes(e)&&(!he.condition||he.condition(l)));if(be){be.handler(l),o({type:"TICK"});return}if(l){let Ve=c.getActions().find(Ge=>Ge.key===e&&(!Ge.condition||Ge.condition(l)));if(Ve){let Ge=Ve.handler(l);typeof Ge=="string"&&_(Ge,Ge.toLowerCase().includes("fail")||Ge.toLowerCase().includes("unavailable")?"error":"info");return}}}if(e==="z"){o({type:"CYCLE_LAYOUT"});let _e=["normal","expanded","wide-side"],be=_e.indexOf(r.layoutMode),he=_e[(be+1)%_e.length];_(`Layout: ${{normal:"Normal",expanded:"Expanded","wide-side":"Wide Side"}[he]}`,"info");return}if(e==="V"){o({type:"SET_OVERLAY",overlay:"changelog"});return}if(e==="r"){z?.();return}if(e==="p"&&U){U(),_(se?"Session unpinned":"Session pinned","info");return}if(e==="f"){T();return}if(e==="x"){l&&c.getActions().length>0&&o({type:"SET_OVERLAY",overlay:"context-menu"});return}if(e==="["){o({type:"CYCLE_DETAIL_TAB",direction:-1,tabCount:E});return}if(e==="]"){o({type:"CYCLE_DETAIL_TAB",direction:1,tabCount:E});return}if(r.focusTarget==="side"){if(e==="j"||t.downArrow){g<h-1&&(o({type:"SELECT_ITEM",index:g+1}),v.selectNext());return}if(e==="k"||t.upArrow){g>0&&(o({type:"SELECT_ITEM",index:g-1}),v.selectPrev());return}if(e==="g"){o({type:"SELECT_ITEM",index:0}),v.selectFirst();return}if(e==="G"){o({type:"SELECT_ITEM",index:Math.max(0,h-1)}),v.selectLast();return}if(t.return){o({type:"SET_FOCUS",target:"detail"});return}}if(r.focusTarget==="detail"){if(e==="j"||t.downArrow){o({type:"SCROLL_DETAIL_DELTA",delta:1,totalLines:I,viewportHeight:x});return}if(e==="k"||t.upArrow){o({type:"SCROLL_DETAIL_DELTA",delta:-1,totalLines:I,viewportHeight:x});return}if(e==="h"||t.leftArrow){o({type:"SET_FOCUS",target:"side"});return}if(e==="g"){o({type:"SCROLL_DETAIL",offset:0});return}if(e==="G"){o({type:"SCROLL_DETAIL",offset:ux(I,x)});return}}}}var nXe,Jxe=B(()=>{"use strict";u1();nXe=new Set(["j","k","g","G","h","q","?","/","M","R","s","A","1","2","3","4","5","6","7","8","9"])});function Wxe(e,t,n){let r=Math.max(0,t-n);return e.slice(Math.max(0,e.length-Math.min(r,e.length)))}var Xxe=B(()=>{"use strict"});function ewe(e,t){let n=e();return{allItems:n,currentItems:t([...n])}}var twe=B(()=>{"use strict"});function SJ(e,t=3){return t<=0?[]:e.slice(Math.max(0,e.length-t))}var nwe=B(()=>{"use strict"});function rwe(){return{loadedAt:null,error:null,refreshing:!1,watcherError:null,watcherErrorAt:null}}function bJ(e,t){return e.error?{text:"\u26A0 data",color:"red"}:e.watcherError!==null&&(e.watcherErrorAt===null||t-e.watcherErrorAt<=6e4)?{text:"\u26A0 session",color:"yellow"}:e.refreshing?{text:"\u21BB",color:"gray"}:e.loadedAt!==null&&t-e.loadedAt>12e4?{text:`stale ${Math.floor((t-e.loadedAt)/6e4)}m`,color:"yellow"}:null}var IJ=B(()=>{"use strict"});function _J({panels:e,metrics:t,staticData:n,isPinned:r,pendingSessionPath:o,onSessionSwitch:i,onTogglePin:s,onGenerateReport:c,mouseInitiallyEnabled:l,onMouseSettingChange:p,onRefresh:h,dataStatus:g,notice:v,accountViews:E,onAccountSwitch:I,onAccountUndo:x}){let[_,T]=(0,Kr.useReducer)(Zxe,Kxe,Qe=>({...Qe,mouseEnabled:l!==!1})),{exit:M}=tm(),{isRawModeSupported:$}=Ka(),{columns:z,rows:U}=Ya(),se=(0,Kr.useRef)(0),H=(0,Kr.useRef)(0),ie=(0,Kr.useRef)(null),oe=(0,Kr.useRef)(!1),W=(0,Kr.useRef)(0),de=(0,Kr.useRef)(null);(0,Kr.useEffect)(()=>{if(!_.hasReceivedEvents&&t.eventCount>0){let Qe=(t.sessionStartTime||"").substring(0,8);T({type:"FIRST_EVENT",sessionPrefix:Qe})}},[t.eventCount,_.hasReceivedEvents,t.sessionStartTime]),(0,Kr.useEffect)(()=>{if(!oe.current){H.current=t.timelineAppendCount,oe.current=!0;return}if(t.timelineAppendCount!==H.current){for(let Qe of Wxe(t.timeline,t.timelineAppendCount,H.current))Qe.type==="summary"?ae(Qe.summary||"Context compacted","warning"):Qe.type==="system"&&Qe.summary?.includes("ended")&&ae(Qe.summary,"info");H.current=t.timelineAppendCount}},[t.timelineAppendCount,t.timeline]);let ae=(0,Kr.useCallback)((Qe,gt)=>{let Mt={error:4e3,warning:3e3,info:2e3},on=++se.current;T({type:"ADD_TOAST",toast:{id:on,message:Qe,severity:gt,expiresAt:Date.now()+Mt[gt]}}),setTimeout(()=>{T({type:"REMOVE_TOAST",id:on})},Mt[gt])},[]),_e=(0,Kr.useRef)(0);(0,Kr.useEffect)(()=>{v&&v.id!==_e.current&&(_e.current=v.id,ae(v.message,v.severity))},[v,ae]),(0,Kr.useEffect)(()=>{if(t.providerId!=="claude-code"){ie.current=null;return}let Qe=$f(t.quota);if(!Qe){ie.current=null;return}ie.current!==Qe.alertKey&&(ie.current=Qe.alertKey,ae(`${Qe.title}: ${Qe.message}`,Qe.severity))},[ae,t.providerId,t.quota]);let be=e[_.activePanelIndex],he=z<sXe||U<aXe,Ge=(()=>{switch(_.layoutMode){case"expanded":return 0;case"wide-side":return Math.min(cXe,z-30);default:return z<80?iXe:oXe}})(),mt=(0,Kr.useCallback)(Qe=>{let gt=Qe;if(_.sessionFilter&&["tasks","kanban","notes","decisions","plans"].includes(be.id)&&(be.id==="kanban"?gt=gt.map(Mt=>uXe(Mt,_.sessionFilter)):gt=gt.filter(Mt=>owe(Mt,_.sessionFilter))),_.filterString){let Mt=_.filterString,on=_.filterMode;if(on==="date"){let ur=mF(Mt);if(!("error"in ur)){let cn=ur.since?Date.parse(ur.since):-1/0,wo=ur.until?Date.parse(ur.until):1/0;gt=gt.filter(ko=>{let ts=be.getItemTimestamp?be.getItemTimestamp(ko):k_e(ko.data);return ts!==null&&ts>=cn&&ts<wo})}}else gt=gt.filter(ur=>{let cn=be.getSearchableText?.(ur)??ur.label.replace(/\{[^}]*\}/g,"");switch(on){case"fuzzy":{let wo=cn.toLowerCase();return Mt.toLowerCase().split(/\s+/).filter(ko=>ko).every(ko=>wo.includes(ko))}case"regex":try{return new RegExp(Mt).test(cn)}catch{return!1}default:return cn.toLowerCase().includes(Mt.toLowerCase())}})}return gt.sort((Mt,on)=>Mt.sortKey-on.sortKey),gt},[be,_.sessionFilter,_.filterString,_.filterMode]),Bt=be.viewVersion??0,{allItems:wr,currentItems:ve}=(0,Kr.useMemo)(()=>ewe(()=>be.getItems(t,n),mt),[be,Bt,t,n,mt]),ot=Math.min(_.selectedItemIndex,Math.max(0,ve.length-1));ot!==_.selectedItemIndex&&ve.length>0&&T({type:"CLAMP_SELECTION",index:ot});let Ht=Math.max(1,U-5),Yt=axe(Ht,ve.length),pn=rxe({totalItems:ve.length,viewportHeight:Yt});(0,Kr.useEffect)(()=>{pn.selectedIndex!==_.selectedItemIndex&&pn.setSelected(_.selectedItemIndex)},[_.selectedItemIndex]);let Zn=ve[ot],Rt=be.detailTabs,Vt=Math.min(_.detailTabIndex,Rt.length-1),xt=(0,Kr.useMemo)(()=>txe(),[Zn?.id,Vt]),rn=Math.max(40,z-Ge-3),it=!!_.sessionFilter,Ot=(0,Kr.useMemo)(()=>{if(Zn&&Rt.length>0&&Vt>=0){let Qe=Rt[Vt],gt=Qe.label;return(gt==="Timeline"||gt==="Mind Map"?"":xt+`
|
|
1140
|
+
`):[],c=s.length,l=ixe(t,c),p=l>0,h=p?1:0,g=c>l+n-1?1:0,v=Math.max(1,n-h-g),E=s.slice(l,l+v),I=l+v<c;return(0,Zh.jsxs)(Ze,{flexDirection:"column",flexGrow:1,borderStyle:i,borderColor:o,paddingLeft:1,children:[p&&(0,Zh.jsx)(Ze,{justifyContent:"center",children:(0,Zh.jsxs)(j,{color:"gray",children:["\u25B2 (",l," more)"]})}),E.map((x,_)=>(0,Zh.jsx)(j,{wrap:"wrap",children:Su(x)},l+_)),E.length<v&&Array.from({length:v-E.length},(x,_)=>(0,Zh.jsx)(j,{children:" "},`pad-${_}`)),I&&(0,Zh.jsx)(Ze,{justifyContent:"center",children:(0,Zh.jsxs)(j,{color:"gray",children:["\u25BC (",c-l-v," more)"]})})]})}var Zh,vxe=B(async()=>{"use strict";await ii();await QC();u1();Zh=Me(On(),1)});function mJ({eventCount:e,providerName:t,permissionMode:n,focusTarget:r,panelHints:o,sessionFilter:i,filterString:s,matchCount:c,totalCount:l,updateInfo:p,providerStatus:h,openaiStatus:g,mouseEnabled:v,dataBadge:E,activeAccount:I}){let x=e>0?`${e} events`:"waiting...",_=n==="bypassPermissions"?"red":n==="acceptEdits"?"magenta":n==="plan"?"green":void 0,T=n==="bypassPermissions"?"BYPASS":n==="acceptEdits"?"EDITS":n==="plan"?"PLAN":void 0,M=h?RC(h):null,$=g?RC(g):null;return(0,pt.jsxs)(Ze,{height:1,width:"100%",children:[(0,pt.jsxs)(Ze,{children:[(0,pt.jsx)(j,{children:Su(xF)}),(0,pt.jsxs)(j,{dimColor:!0,children:[" v","0.28.1"]}),p&&(0,pt.jsxs)(j,{color:"yellow",children:[" (v",p.latest,")"]})]}),(0,pt.jsxs)(Ze,{flexGrow:1,justifyContent:"center",children:[t&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:"cyan",children:t})]}),I&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsxs)(j,{color:I.color,children:["\u2394"," ",I.label]})]}),n&&n!=="default"&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:_,children:T})]}),(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{children:x}),M?.visible&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:M.color,children:M.summary})]}),$?.visible&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:$.color,children:$.summary})]}),v===!1&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:"yellow",children:"MOUSE OFF"})]}),E&&(0,pt.jsxs)(pt.Fragment,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:[" ","\u2502"," "]}),(0,pt.jsx)(j,{color:E.color,children:E.text})]}),s&&(0,pt.jsxs)(j,{color:"yellow",children:[" ",'filter: "',s,'" (',c??0,"/",l??0,")"]}),i&&(0,pt.jsxs)(j,{color:"magenta",children:[" ",i]})]}),(0,pt.jsxs)(Ze,{children:[(0,pt.jsxs)(j,{dimColor:!0,children:["\u2502"," "]}),r==="side"?(0,pt.jsxs)(j,{children:[(0,pt.jsx)(j,{bold:!0,children:"\u2191\u2193"}),(0,pt.jsx)(j,{dimColor:!0,children:" nav "}),(0,pt.jsx)(j,{bold:!0,children:"Tab"}),(0,pt.jsx)(j,{dimColor:!0,children:" detail "}),o,(0,pt.jsx)(j,{bold:!0,children:"/"}),(0,pt.jsx)(j,{dimColor:!0,children:" filter "}),(0,pt.jsx)(j,{bold:!0,children:"?"}),(0,pt.jsx)(j,{dimColor:!0,children:" help "}),(0,pt.jsx)(j,{bold:!0,children:"q"}),(0,pt.jsx)(j,{dimColor:!0,children:" quit"})]}):(0,pt.jsxs)(j,{children:[(0,pt.jsx)(j,{bold:!0,children:"j/k"}),(0,pt.jsx)(j,{dimColor:!0,children:" scroll "}),(0,pt.jsx)(j,{bold:!0,children:"[]"}),(0,pt.jsx)(j,{dimColor:!0,children:" tab "}),(0,pt.jsx)(j,{bold:!0,children:"Tab"}),(0,pt.jsx)(j,{dimColor:!0,children:" side "}),o,(0,pt.jsx)(j,{bold:!0,children:"?"}),(0,pt.jsx)(j,{dimColor:!0,children:" help "}),(0,pt.jsx)(j,{bold:!0,children:"q"}),(0,pt.jsx)(j,{dimColor:!0,children:" quit"})]})]})]})}var pt,Cxe=B(async()=>{"use strict";lF();await ii();c1();await QC();pt=Me(On(),1)});function Sxe(e=ZWe){let[t,n]=(0,kF.useState)(0);return(0,kF.useEffect)(()=>{let r=setInterval(()=>{n(o=>(o+1)%Exe.length)},e);return()=>clearInterval(r)},[e]),Exe[t]}var kF,Exe,ZWe,bxe=B(()=>{"use strict";kF=Me(fn(),1),Exe=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2807","\u280F"],ZWe=80});function _xe({panelCount:e}){let t=Sxe(),n=(0,Ixe.useMemo)(()=>MT(),[]),{columns:r}=Ya(),o=e&&e>1?`1-${Math.min(e,9)}`:"1-9";return(0,si.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",paddingX:2,paddingY:1,width:Math.min(60,r-2),children:[ax.map((i,s)=>(0,si.jsx)(j,{children:Su(i)},s)),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{color:"gray",children:[" ",n]}),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{children:[" ",(0,si.jsx)(j,{color:"magenta",children:t})," ",(0,si.jsx)(j,{color:"gray",children:"Waiting for session events..."})]}),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{children:[" ",(0,si.jsx)(j,{color:"gray",children:"Navigate:"})," ",(0,si.jsx)(j,{bold:!0,children:o})," jump ",(0,si.jsx)(j,{bold:!0,children:"?"})," ","help ",(0,si.jsx)(j,{bold:!0,children:"q"})," quit"]}),(0,si.jsx)(j,{children:" "}),(0,si.jsx)(j,{color:"gray",children:" Start a Claude Code, OpenCode, or Codex session"}),(0,si.jsx)(j,{color:"gray",children:" in another terminal and events will appear here."}),(0,si.jsx)(j,{children:" "}),(0,si.jsxs)(j,{children:[" ",(0,si.jsx)(j,{color:"gray",children:"Or use "}),(0,si.jsx)(j,{bold:!0,children:"--replay"}),(0,si.jsx)(j,{color:"gray",children:" to replay an existing session."})]})]})}var Ixe,si,xxe=B(async()=>{"use strict";Ixe=Me(fn(),1);await ii();bxe();Pt();c1();await QC();Gh();si=Me(On(),1)});function ai(e,t,n=14,r=54){let o=n-e.length,i=Math.max(1,r-n-t.length),s="\xB7".repeat(i);return(0,xi.jsxs)(j,{children:[" ",(0,xi.jsx)(j,{bold:!0,children:e})," ".repeat(Math.max(0,o))," ",(0,xi.jsx)(j,{dimColor:!0,children:s})," ",t]})}function wxe({panels:e,activePanelIndex:t,scrollOffset:n,onClampScroll:r}){let{columns:o,rows:i}=Ya(),s=e[t],c=s.getActions(),l=s.getKeybindings?.()||[],p=[];p.push((0,xi.jsx)(j,{bold:!0,children:" Panels"}));for(let _ of e)p.push(ai(String(_.shortcutKey),_.title));if(p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsx)(j,{bold:!0,children:" Navigation"})),p.push(ai("Tab","Toggle side / detail focus")),p.push(ai("j / \u2193","Next item / scroll down")),p.push(ai("k / \u2191","Prev item / scroll up")),p.push(ai("g / G","First / last item")),p.push(ai("Enter","Focus detail pane")),p.push(ai("h / \u2190","Return to side")),p.push(ai("[ / ]","Cycle detail tabs")),p.push(ai("z","Cycle layout mode")),p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsx)(j,{bold:!0,children:" Actions"})),p.push(ai("x","Context menu")),p.push(ai("/","Filter side list")),p.push(ai("f","Toggle session filter")),c.length>0||l.length>0){p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsxs)(j,{bold:!0,children:[" ",s.title," Actions"]}));for(let _ of c)p.push(ai(_.key,_.label));for(let _ of l)p.push(ai(_.keys.join("/"),_.label))}p.push((0,xi.jsx)(j,{children:" "})),p.push((0,xi.jsx)(j,{bold:!0,children:" General"})),p.push(ai("R","Refresh project data")),p.push(ai("r","Generate HTML report")),p.push(ai("p","Pin session (stop auto-switch)")),p.push(ai("s","Switch to pending session")),p.push(ai("A","Accounts: switch / undo")),p.push(ai("M","Toggle mouse capture (copy/select)")),p.push(ai("V","Version & changelog")),p.push(ai("?","Toggle this help")),p.push(ai("Esc","Close overlay / clear filter")),p.push(ai("q / Ctrl+C","Quit"));let h=Math.max(5,i-12),g=Math.max(0,p.length-h);hJ.default.useEffect(()=>{n>g&&r?.(g)},[n,g,r]);let v=Math.min(n,g),E=p.slice(v,v+h),I=v>0,x=v+h<p.length;return(0,xi.jsx)(Ze,{flexGrow:1,alignItems:"center",justifyContent:"center",children:(0,xi.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",paddingX:1,paddingY:1,width:Math.min(60,o-2),children:[ax.map((_,T)=>(0,xi.jsx)(j,{children:Su(_)},`logo-${T}`)),(0,xi.jsx)(j,{children:" "}),I?(0,xi.jsx)(j,{color:"gray",children:" \u25B2 scroll up (k)"}):(0,xi.jsx)(j,{children:" "}),E.map((_,T)=>(0,xi.jsx)(hJ.default.Fragment,{children:_},`row-${v+T}`)),x?(0,xi.jsx)(j,{color:"gray",children:" \u25BC scroll down (j)"}):(0,xi.jsx)(j,{children:" "})]})})}var hJ,xi,kxe=B(async()=>{"use strict";hJ=Me(fn(),1);await ii();c1();await QC();Gh();xi=Me(On(),1)});function Dxe({actions:e,selectedIndex:t}){let{columns:n,rows:r}=Ya();if(e.length===0)return(0,nm.jsx)(Ze,{});let o=Math.max(...e.map(s=>s.key.length+s.label.length+4),20),i=Math.min(o+6,50,n-2);return(0,nm.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",width:i,position:"absolute",marginLeft:Math.max(0,Math.floor((n-i)/2)),marginTop:Math.max(0,Math.floor((r-e.length-2)/2)),children:[(0,nm.jsx)(j,{color:"magenta",children:" Actions "}),e.map((s,c)=>(0,nm.jsx)(Ze,{children:c===t?(0,nm.jsxs)(j,{inverse:!0,children:[" ",(0,nm.jsx)(j,{bold:!0,children:s.key})," ",s.label]}):(0,nm.jsxs)(j,{children:[" ",(0,nm.jsx)(j,{bold:!0,children:s.key})," ",s.label]})},s.key))]})}var nm,Txe=B(async()=>{"use strict";await ii();Gh();nm=Me(On(),1)});function gJ({views:e,selectedIndex:t}){let{columns:n,rows:r}=Ya(),o=fB(e),i=Date.now(),s=6+o.name+(o.email?o.email+2:0)+(o.plan?o.plan+2:0)+24,c=Math.min(Math.max(44,s),n-2),l=e.length+6,p=null,h=-1;return(0,Ja.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",width:c,position:"absolute",marginLeft:Math.max(0,Math.floor((n-c)/2)),marginTop:Math.max(0,Math.floor((r-l)/2)),paddingX:1,children:[(0,Ja.jsx)(j,{color:"magenta",children:" Accounts "}),e.length===0&&(0,Ja.jsx)(j,{dimColor:!0,children:"No saved accounts. Run: sidekick accounts add"}),e.map(g=>{h++;let v=g.providerId!==p?ms[g.providerId]:null;p=g.providerId;let E=S_(g,i);return(0,Ja.jsxs)(Ze,{flexDirection:"column",children:[v&&(0,Ja.jsx)(j,{bold:!0,children:v}),(0,Ja.jsxs)(j,{inverse:h===t,children:[" ",(0,Ja.jsx)(j,{color:"green",children:g.isActive?"* ":" "}),E.name.padEnd(o.name),o.email?(0,Ja.jsxs)(j,{dimColor:!0,children:[" ",E.email.padEnd(o.email)]}):""," ",(0,Ja.jsxs)(j,{color:E.badge.color,children:[E.badge.glyph," ",E.badge.state]})]})]},`${g.providerId}:${g.id}`)}),(0,Ja.jsxs)(j,{dimColor:!0,children:[(0,Ja.jsx)(j,{bold:!0,children:"Enter"})," switch ",(0,Ja.jsx)(j,{bold:!0,children:"u"})," undo ",(0,Ja.jsx)(j,{bold:!0,children:"a/l/s"})," via CLI"," ",(0,Ja.jsx)(j,{bold:!0,children:"Esc"})," close"]})]})}var Ja,Bxe=B(async()=>{"use strict";await ii();gC();Gh();Ja=Me(On(),1)});function Rxe({filterString:e,filterMode:t,filterError:n}){let{rows:r}=Ya();return(0,Sd.jsxs)(Ze,{position:"absolute",marginTop:r-2,width:"100%",height:1,children:[YWe.map(o=>{let{key:i,label:s}=KWe[o];return(0,Sd.jsx)(j,{children:o===t?(0,Sd.jsxs)(j,{bold:!0,color:"magenta",children:["[",i,"]",s," "]}):(0,Sd.jsxs)(j,{color:"gray",children:["[",i,"]",s," "]})},o)}),(0,Sd.jsxs)(j,{bold:!0,color:"magenta",children:[" ","/"," "]}),n?(0,Sd.jsx)(j,{color:"red",children:e}):(0,Sd.jsx)(j,{children:e}),(0,Sd.jsx)(j,{color:"gray",children:"\u2588"}),n&&(0,Sd.jsxs)(j,{color:"red",children:[" ",n]}),t==="date"&&!e&&(0,Sd.jsx)(j,{color:"gray",children:" today \xB7 yesterday \xB7 2d \xB7 1w \xB7 YYYY-MM-DD \xB7 >expr \xB7 <expr"})]})}var Sd,KWe,YWe,$xe=B(async()=>{"use strict";await ii();Gh();Sd=Me(On(),1),KWe={substring:{key:"S",label:"Substr"},fuzzy:{key:"F",label:"Fuzzy"},regex:{key:"R",label:"Regex"},date:{key:"D",label:"Date"}},YWe=["substring","fuzzy","regex","date"]});function Qxe({entries:e,scrollOffset:t,onClampScroll:n}){let{columns:r,rows:o}=Ya(),i=Math.min(64,r-2),s=Math.max(o-12,10),c=[],l=e[0]?.date||"";c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsxs)(j,{bold:!0,color:"cyan",children:["Terminal Dashboard v","0.28.1"]}),l?(0,no.jsxs)(j,{color:"gray",children:[" \u2014 ",l]}):null]},"ver")),c.push((0,no.jsx)(j,{children:" "},"sep"));for(let I=0;I<e.length;I++){let x=e[I];I>0&&c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsxs)(j,{bold:!0,children:["v",x.version]}),(0,no.jsxs)(j,{color:"gray",children:[" \u2014 ",x.date]})]},`v-${I}`));for(let _ of x.sections){c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsx)(j,{bold:!0,color:"yellow",children:_.heading})]},`h-${I}-${_.heading}`));for(let T=0;T<_.items.length;T++){let M=i-8,$=_.items[T];$.length>M&&($=$.slice(0,M-1)+"\u2026"),c.push((0,no.jsxs)(j,{children:[" ",(0,no.jsx)(j,{color:"gray",children:"\u2022"})," ",$]},`item-${I}-${_.heading}-${T}`))}}I<e.length-1&&c.push((0,no.jsx)(j,{children:" "},`gap-${I}`))}let p=Math.max(0,c.length-s);Mxe.default.useEffect(()=>{t>p&&n?.(p)},[t,p,n]);let h=Math.min(t,p),g=c.slice(h,h+s),v=h>0,E=h+s<c.length;return(0,no.jsx)(Ze,{flexGrow:1,alignItems:"center",justifyContent:"center",children:(0,no.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"magenta",paddingX:1,paddingY:1,width:i,children:[(0,no.jsxs)(j,{children:[" ",(0,no.jsxs)(j,{bold:!0,color:"magenta",children:["\u26A1"," W H A T ' S N E W"]})]}),(0,no.jsx)(j,{children:" "}),v&&(0,no.jsx)(j,{color:"gray",children:" \u25B2 scroll up (k)"}),g,E&&(0,no.jsx)(j,{color:"gray",children:" \u25BC scroll down (j)"}),(0,no.jsx)(j,{children:" "}),(0,no.jsxs)(j,{color:"gray",children:[" ","Full changelog:"," ",(0,no.jsx)(j,{color:"cyan",children:"https://cesarandreslopez.github.io/sidekick-agent-hub/changelog/"})]}),(0,no.jsx)(j,{children:" "}),(0,no.jsxs)(j,{color:"gray",children:[" ","Press ",(0,no.jsx)(j,{bold:!0,children:"Esc"})," or ",(0,no.jsx)(j,{bold:!0,children:"V"})," to close"]})]})})}var Mxe,no,Oxe=B(async()=>{"use strict";Mxe=Me(fn(),1);await ii();Gh();no=Me(On(),1)});function Nxe({columns:e,rows:t}){return(0,lx.jsx)(Ze,{flexDirection:"column",width:e,height:t,justifyContent:"center",alignItems:"center",children:(0,lx.jsxs)(Ze,{flexDirection:"column",borderStyle:"single",borderColor:"red",paddingX:2,paddingY:1,children:[(0,lx.jsx)(j,{color:"red",children:"Terminal too small"}),(0,lx.jsxs)(j,{color:"gray",children:["Need at least 60x15 (current: ",e,"x",t,")"]})]})})}var lx,Pxe=B(async()=>{"use strict";await ii();lx=Me(On(),1)});function AJ({toast:e,row:t=0}){let{columns:n}=Ya(),r=VWe[e.severity]||"cyan",o=JWe[e.severity]||"\u25CF",i=Math.max(16,Math.min(56,n-10)),s=e.message.length>i?e.message.substring(0,i-3)+"...":e.message;return(0,DF.jsx)(Ze,{position:"absolute",marginLeft:Math.max(0,n-s.length-8),marginTop:t*3,borderStyle:"single",borderColor:r,paddingX:1,children:(0,DF.jsxs)(j,{color:r,children:[o," ",s]})})}var DF,VWe,JWe,zxe=B(async()=>{"use strict";await ii();Gh();DF=Me(On(),1),VWe={error:"red",warning:"yellow",info:"cyan"},JWe={error:"\u2718",warning:"\u26A0",info:"\u25CF"}});function yJ(e=process.stdout){e.isTTY&&(e.write("\x1B[?1000h"),e.write("\x1B[?1002h"),e.write("\x1B[?1006h"))}function dx(e=process.stdout){e.isTTY&&(e.write("\x1B[?1006l"),e.write("\x1B[?1002l"),e.write("\x1B[?1000l"))}var vJ=B(()=>{"use strict"});function Fxe(e){let t=typeof e=="string"?e:e.toString("utf-8");return Array.from(t.matchAll(WWe),XWe).filter(n=>n!==null)}function XWe(e){let t=parseInt(e[1],10),n=parseInt(e[2],10),r=parseInt(e[3],10),o=e[4]==="m",i=n-1,s=r-1,c=(t&4)!==0,l=(t&8)!==0,p=(t&16)!==0,h=t&-29;return h===64||h===65?{type:"scroll",button:"none",x:i,y:s,shift:c,meta:l,ctrl:p,scrollDirection:h===64?"up":"down"}:h>=32&&h<=34?{type:"drag",button:["left","middle","right"][h-32],x:i,y:s,shift:c,meta:l,ctrl:p}:h>=0&&h<=2?{type:o?"release":"click",button:["left","middle","right"][h],x:i,y:s,shift:c,meta:l,ctrl:p}:null}var WWe,CJ=B(()=>{"use strict";WWe=/\x1b\[<(\d+);(\d+);(\d+)([Mm])/g});function Uxe(e){return t=>{for(let n of Fxe(t))e.current(n)}}var Lxe=B(()=>{"use strict";CJ()});function eXe({active:e}){return Cd(()=>{},{isActive:e}),null}function BF({onMouse:e,enabled:t=!0,children:n}){let r=(0,TF.useRef)(e);r.current=e;let{isRawModeSupported:o}=Ka();return(0,TF.useEffect)(()=>{if(!t||!o)return;yJ();let i=Uxe(r);process.stdin.on("data",i);let s=()=>dx();return process.on("exit",s),()=>{process.stdin.removeListener("data",i),process.removeListener("exit",s),dx()}},[t,o]),(0,fx.jsxs)(fx.Fragment,{children:[(0,fx.jsx)(eXe,{active:o}),n]})}var TF,fx,jxe=B(async()=>{"use strict";TF=Me(fn(),1);await ii();vJ();Lxe();fx=Me(On(),1)});var EJ=B(async()=>{"use strict";vJ();CJ();await jxe()});var Gxe,Hxe=B(()=>{Gxe="# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.28.1] - 2026-10-18\n\n### Changed\n\n- Bundles `sidekick-shared` 0.28.1 (the test credential guard keeps `promisify(execFile)` returning `{ stdout, stderr }`); no CLI-visible changes.\n\n## [0.28.0] - 2026-10-18\n\n### Fixed\n\n- **Sessions under a custom Claude home are read** (bundled `sidekick-shared`). With `CLAUDE_CONFIG_DIR` set, `dashboard`, `dump`, `report`, `daily` / `weekly` / `monthly` / `sessions`, `blocks`, `search`, `doctor`, and plan reading follow the home Claude Code writes to instead of only `~/.claude`.\n- **Archived Codex sessions stay visible** (bundled `sidekick-shared`): sessions Codex moved to `archived_sessions/` are listed, found by id, and counted in usage reports.\n- **Long-running session watching stays bounded** (bundled `sidekick-shared`): `dashboard` and `dump` read a large backlog in chunks, skip a line over 16 MiB, and re-read a session file that is truncated, rewritten, or replaced from the start; the dashboard then drops the metrics built from the old content instead of counting the session twice.\n\n### Changed\n\n- The CLI's main bundle shrinks from 2.85 MB to 2.47 MB: it now bundles `sidekick-shared` from its tree-shakable ES-module build.\n\n## [0.27.6] - 2026-09-26\n\n### Added\n\n- `sidekick accounts doctor` adds a \"Claude credential stores\" section: stored credentials Sidekick owns that no account uses, a second copy of the live login, and unreadable (truncated) credentials. `--fix` repairs them after asking; `--yes` skips the prompt, and `--json` output lists what was repaired. Ownership is proven by a ledger and a Keychain comment tag, never by the item name.\n\n### Fixed\n\n- **Claude logins are no longer invalidated by Sidekick** (bundled `sidekick-shared`). Claude Code rotates the refresh token on every refresh, so every usable copy of a login but one dies with \"Not logged in \xB7 Please run /login\"; Sidekick now keeps exactly one.\n - Keychain writes larger than about 4 KB are no longer truncated into an unreadable credential, and every write is read back before it counts.\n - The live account no longer keeps a second usable copy in its profile directory; `accounts switch` saves the outgoing login first (even with `--force`), holds Claude Code's refresh lock, never overwrites a newer login, and keeps the live MCP server tokens.\n - Keep-alive never refreshes a copy of a live login. `accounts shell` / `env` for the live account use the normal Claude home.\n - `sidekick account --launcher` scripts resolve the account's home when they run instead of pinning a profile directory.\n - In a shell from `sidekick accounts env` or `shell`, commands no longer remove that account's login as a supposed second copy of the live login.\n- **Codex logins get the same protection** (bundled `sidekick-shared`): verified private backups replace runnable profile copies and timestamped stashes, `accounts switch` is refused while Codex CLI, app, or IDE sessions run (`--force` does not bypass it) and is journaled so an interrupted switch finishes or rolls back, and keep-alive refreshes through `codex app-server`.\n- `accounts doctor` no longer syncs accounts or rewrites health metadata while inspecting, and `--fix` also repairs Codex duplicates, stale stashes, orphaned copies, and interrupted switches, honouring `--provider` and the confirmation prompt.\n\n## [0.27.5] - 2026-09-23\n\n### Added\n\n- `sidekick dump --prompts` prints every human prompt of Claude Code and Codex sessions grouped by session, for reading or classifying a whole session. The default is the most recent session with prompts.\n - **Selecting sessions.** `--session <id-or-prefix>` picks one session. `--all` takes every session of the project and its git worktrees, optionally narrowed by `--since <time>` (sessions active since then, returned whole) and `--limit <n>`.\n - **Extra content.** `--replies` adds the agent's final reply to each prompt, and `--signals` adds interrupts, rejected and failed tool calls, compactions, API errors, and rollbacks.\n - **Output.** `--format` accepts `text`, `markdown`, `json` (the full result, with bounds and stats), or `jsonl` (one session per line). Bounded calls continue automatically until every session is read, and a reader that stops early (`| head`) ends the dump quietly.\n - **Providers.** Both are read unless `--provider claude-code` or `--provider codex` is given; OpenCode exits with an error.\n\n## [0.27.4] - 2026-09-23\n\n### Changed\n\n- Bundles `sidekick-shared` 0.27.4 (new `sidekick-shared/node` exports and an optional abort signal for `collectUsageEvents()`); no CLI-visible changes.\n\n## [0.27.3] - 2026-09-23\n\n### Fixed\n\n- Token totals no longer double-count Claude Code split lines or repeated Codex `token_count` events (via `sidekick-shared` 0.27.3). This corrects `dump`, `report`, the dashboard, `daily`/`weekly`/`monthly`/`sessions`, and `blocks`; the usage cache rebuilds itself on first run.\n\n### Added\n\n- `sidekick dump` shows the session's subagents: text and markdown add \"Subagents (n)\" and \"Session total (incl. subagents)\", and `--format json` adds a `tokenSummary` block (`mainThread`, `subagents`, `subagentTotal`, `combined`). `sidekick report` adds the same cards.\n- The dashboard's Sessions panel leads its Tokens section with \"Total (incl. cache)\" and lists every bucket, then subagent and session totals (subagent transcripts are rescanned every 15 s). Its state file writes `context.totalTokens`.\n\n### Changed\n\n- Cache hit rate counts cache writes, per-event token suffixes and the event detail show cache-inclusive totals, and the dashboard's cost comes from `costUsd`. Claude subagent transcripts now count toward the usage reports under their parent session.\n\n## [0.27.2] - 2026-09-22\n\n### Changed\n\n- Bundles `sidekick-shared` 0.27.2 (streamed, resumable prompt history); no CLI-visible changes.\n\n## [0.27.1] - 2026-09-22\n\n### Changed\n\n- Bundles `sidekick-shared` 0.27.1 (prompt-history late answer metadata); no CLI-visible changes.\n\n## [0.27.0] - 2026-09-22\n\n### Changed\n\n- Dashboard session summaries sent through the OpenAI API use GPT-6 Luna (`gpt-6-luna`) instead of GPT-5.6 Luna; GPT-6 Sol and Luna sessions get pricing and context-window metadata via `sidekick-shared` 0.27.0.\n\n### Fixed\n\n- Cost estimates for Claude Opus 5.5 (`claude-opus-5-5`) sessions use its own rates ($4 / $20 per 1M tokens, $0.20 cache reads) instead of Opus 5's, via `sidekick-shared` 0.27.0.\n\n## [0.26.6] - 2026-09-16\n\n### Added\n\n- `sidekick accounts`: an interactive picker (arrow keys, `Enter` switch, `a` add, `l` sign in again, `r` remove, `s` shell, `u` undo) plus `list`, `add`, `switch`, `login`, `remove`, `shell`, `env`, `undo`, `doctor`, and `config` subcommands. Lists show credential health and expiry; switches print `\u2713 verified`, one line per running app that still holds the previous login, and the undo command; `env` renders bash/zsh/fish/PowerShell/cmd exports and `shell` opens a subshell or runs one command as a saved account on every platform.\n- `sidekick accounts doctor` reports per-account expiry, running `claude`/`codex` processes and desktop apps, the Codex credential-store mode, and the keep-alive state; `accounts config keep-alive on` makes the dashboard refresh inactive accounts hourly through the official CLIs.\n- Dashboard: `A` opens an accounts overlay (`Enter` switch, `u` undo) and the status bar shows the active account coloured by health.\n\n### Changed\n\n- Every `accounts` command first folds live logins into the registry and prints `Registered <email>` on stderr for logins it had never seen; `list` prints first-run guidance while all accounts were learned automatically.\n\n### Fixed\n\n- The dashboard status-bar account now follows the monitored provider (the Codex provider is displayed as `Codex CLI`, so the badge always showed the Claude account before), and the overlay's `u` undoes the provider that actually has a switch to revert instead of whichever provider has saved accounts.\n- The interactive picker reports the real outcome of `u` and `r`: a failed undo or remove shows the error instead of `Undone.` / `Removed \u2026`, and a successful undo shows the switch headline rather than the trailing hint.\n- `accounts switch --next` with no saved accounts says so instead of claiming two providers have accounts.\n\n### Deprecated\n\n- `sidekick account --\u2026` flags: still work, print the equivalent `sidekick accounts \u2026` command on stderr, and now delegate to the same actions. `--launcher` remains POSIX-only; `accounts shell` / `accounts env` are the cross-platform replacements.\n\n## [0.26.5] - 2026-09-15\n\n### Changed\n\n- `sidekick dashboard` newer-session detection reconciles each watched-file event with one stat, and catch-up polls cost one stat per unchanged directory instead of walking every session file.\n\n## [0.26.4] - 2026-09-09\n\n### Fixed\n\n- AI summary failures distinguish refresh-token rejection from expired conversations and recognize expired-login and reauthentication messages with guidance appropriate to the known credential kind.\n- Policy-denial messages, including HTTP 403 responses, direct users to review execution permissions.\n\n## [0.26.3] - 2026-09-09\n\n### Added\n\n- `sidekick status --json` includes `serviceStatus` evidence alongside existing Claude, OpenAI, and peak-hour fields. Human-readable output and dashboard details include multiple incidents, component associations, and separate check/provider-update timestamps.\n\n### Fixed\n\n- Status displays distinguish unavailable and partial evidence, including omitted incident data. Dashboard polling coalesces overlapping checks and cancels outstanding checks when stopped.\n- AI summary failures retain structured provider diagnoses and show appropriate authentication, session, service, connection, policy, runtime, and context guidance without automatic replay or provider switching.\n\n## [0.26.2] - 2026-09-06\n\n### Fixed\n\n- CLI live-only sessions no longer overwrite complete-history checkpoints. Older CLI checkpoints are invalidated and replayed once.\n- OpenCode dashboards replay history instead of restoring timestamp-only snapshots, preventing duplicate token totals on reopen.\n- Dashboard checkpoints save after complete event batches, use the current snapshot schema, and reject obsolete or incompatible consumer formats.\n- Project-scoped search passes the workspace path through shared provider discovery, including Codex and database-only OpenCode sessions.\n- Doctor honors `--provider`; unused integrations and missing saved accounts are informational when monitoring existing sessions.\n- Shared watchers preserve partial UTF-8 lines and use OpenCode's platform-specific data directory.\n\n## [0.26.1] - 2026-09-05\n\n### Changed\n\n- Direct OpenAI API dashboard summaries use GPT-5.6 Luna with reasoning disabled and a 1,024-token `max_completion_tokens` limit. Anthropic API summaries retain Haiku 4.5; native CLI summaries retain the user's model configuration.\n\n### Fixed\n\n- Shared model metadata verified on 2026-09-05 corrects fallback costs and context gauges for Fable 5.1, GPT-6 Astra, GPT-5.6, and GPT-5.4 mini/nano.\n- Codex `quota`, `quota --provider codex`, `quota --all`, and MCP quota queries fetch live utilization and reset credits on every call. Local samples no longer prevent API refreshes, including with `--refresh`.\n- Codex fallback output shows sample age and the failed API refresh reason; older logs no longer hide newer cached data.\n\n## [0.26.0] - 2026-09-05\n\n### Added\n\n- `sidekick statusline` reads the JSON Claude Code pipes to its status-line command (`SIDEKICK_STATUSLINE_STDIN=0` disables it), appends context %, session cost, and prompt-cache hit rate, and persists the official five-hour and seven-day limits to the quota snapshot and history stores, so every other command and dashboard sees them without a network call. Cached quota older than five minutes is labelled with its age\n- Global `--offline` (or `SIDEKICK_OFFLINE=1`) prices from the cached catalog only; global `--output-file <path>` writes a command's stdout to a file (not for `dashboard` or `mcp`)\n- `stats --csv` prints every recorded day; `dump --list --csv` and `quota history --csv` print their tables as CSV\n- `quota history --window 5h|7d|max` selects which limit the heatmap shows (default `5h`); the header names the window\n- The global `--json` flag applies to `tasks add`, `tasks done`, `note add`, `decision add` (returning the stored record) and to `report` (returning the output path)\n- The dashboard raises a toast when the five-hour window crosses 80% or 95%, or the seven-day window crosses 90%, once per reset window\n- `sidekick blocks [--active | --recent | --since <time>] [--csv] [--no-cache]` shows five-hour billing blocks computed from session logs (a block opens at the first usage event aligned to the UTC hour, lasts five hours, and a longer gap opens a new one) with cache-inclusive totals, cost provenance, burn rate, and \u2014 for the open block \u2014 projected end-of-block tokens and cost. Sessions are read once and cached by size and mtime; the table is labelled a local estimate and the official status-line sample is shown beneath it when present. `--since` accepts an ISO date, `YYYY-MM-DD`, or a relative window such as `7d`\n- The dashboard's Sessions summary shows the active five-hour billing block (local estimate from session logs), refreshed every minute\n- `sidekick daily`, `weekly`, `monthly`, and `sessions` report usage computed straight from session logs, so CLI-only users no longer see \"No historical data found\". Every provider with session data is read by default (the global `--provider` narrows to one); rows are bucketed by the time of each usage event on the local calendar (`--utc` for UTC), so a session crossing midnight is split across both days; weeks start on Monday. Options: `--since` / `--until` (ISO date, `YYYY-MM-DD`, or relative windows such as `30d`), `--breakdown` (per-model sub-rows), `--by-project`, `--csv`, `--no-cache`; the global `--json` prints the full report. Defaults: 30 days, 12 weeks, 12 calendar months, 30 days\n- `sidekick stats` points at `sidekick daily` when the history store is empty\n- `sidekick import [--since <time>]` folds finished sessions from every detected provider (or the global `--provider`) into `historical-data.json`, the store behind `stats`, `today`, and the VS Code History tab, using the same importer and store mutation as the extension. Files already imported, sessions already persisted by the live monitor, and files modified in the last minute are skipped; session logs are read without holding the store lock and the summaries are applied in one short locked write that re-checks the on-disk store\n- `sidekick statusline` writes `~/.config/sidekick/state.json` on every prompt (only when something changed) and the dashboard writes it on quota updates and billing-block ticks: a public, versioned (`schemaVersion: 1`) document with the active account, quota windows with freshness, context usage, session cost, and the active billing block, for tmux status bars, menu-bar apps, and scripts\n\n### Changed\n\n- Startup awaits bounded pricing-catalog hydration, so two runs of the same command price identically; a fresh cache is a local read and a refresh is capped by the catalog's 3 s timeout\n- Every token total (`stats`, `today`, the dashboard session panel, `dump`, `report`) includes cache reads and writes and is labelled \"Total (incl. cache)\"; cost figures carry their provenance\n- `sidekick today` looks up yesterday by local calendar day (the history store has always been keyed that way) and takes its peak-hours line from the shared schedule, so it agrees with `sidekick peak`\n- `sidekick quota` shows the age of a cached snapshot and only colours it as a warning when it is older than five minutes; `quota history` reads providers in parallel\n- The global `--json` flag applies to `dump` (same as `--format json`)\n- Commands set `process.exitCode` instead of calling `process.exit(1)` on errors, so piped output is never truncated\n- The status line no longer writes to the account registry on its hot path\n- `sidekick quota`, `quota --all`, and `mcp get_quota_status` resolve quota through the shared `resolveQuota()` precedence (fresh persisted sample, then session logs, then the provider API, then an older sample), so a fresh status-line sample is never outranked by an older session-derived value and `--all` no longer forces Codex API-first; `--refresh` asks the API first for every provider, not only Codex\n- Every quota table prints a `Source` row naming where the numbers came from (`cached status-line sample from \u2026 (3m ago)`, `local session logs`, `Anthropic usage API`, \u2026); JSON output adds `resolution`, `capturedSource`, `freshness`, and `ageMs`\n- `sidekick report` and the dashboard's report action read the session once through its provider reader and derive both the metrics and the transcript from those events, instead of replaying the session through a watcher and then parsing the file again; report metrics now come from the canonical event path (the same one `readSessionStats()` uses)\n- Codex session discovery, listings, and the local quota scan use the shared capped walker, so the dashboard's session poll and `sidekick quota` no longer enumerate and re-read the whole rollout history on every call\n- The dashboard detects new sessions by subscribing to the provider's session root (`fs.watch` with a 30 s catch-up poll) instead of walking the session corpus every 10 s; the followed session's own writes no longer trigger a lookup\n- `DashboardState.getMetrics()` returns the same object until the next mutation, and the dashboard memoises panel items and detail rendering on that identity (plus each panel's `viewVersion`), so key presses, scrolling, and toasts no longer rebuild every panel\n- Provider status polling is scoped to the active provider: status.claude.com for Claude Code, status.openai.com for Codex, nothing for OpenCode\n- `sidekick dump --list` and the multi-provider session picker read the bounded async preview index; `--list` prints enumeration diagnostics to stderr and shows the \"raise --limit\" footer only when more sessions exist beyond the limit\n- `sidekick stats` text mode: the Top Failing Tools block shows the last 7 and 30 days side by side with a trend arrow; `--json` output is unchanged\n\n### Fixed\n\n- `--offline` and `--output-file` given before the command are recognised by the command-token scan: `sidekick --offline stats` used to skip catalog hydration entirely and price from the static table, and `sidekick --offline statusline` fell off the fast path\n- `--output-file` writes plain text: chalk's colour level is reset when the redirect is installed, unless `FORCE_COLOR` is set\n- The dashboard's `state.json` keys quota by the sample's `providerId` when one is stamped\n\n## [0.25.0] - 2026-08-18\n\n### Changed\n\n- The CLI advances in lockstep with `sidekick-shared` 0.25.0 and retains its existing commands and synchronous compatibility surface\n\n## [0.24.5] - 2026-08-18\n\n### Added\n\n- `sidekick history` lists recent Codex user prompts across every workspace from `~/.codex/history.jsonl`, newest first, as an AGE / SESSION / PROMPT table sized to the terminal. `--limit <n>` bounds the count (default 20) and the underlying tail read scales with the limit, so large limits are not silently truncated. `--path <id-or-prefix>` resolves a full session id or unique prefix to its rollout transcript path \u2014 `less \"$(sidekick history --path 0198a3c2)\"` \u2014 and the global `--json` emits full ids and ISO timestamps. Codex-only for now; not to be confused with `sidekick quota history`\n- `sidekick dump --list` gains `--limit <n>` (default 50). The listing and the interactive session picker both read the shared session-preview index, which stats first and content-reads only the sessions actually shown \u2014 listing a project with a large session history no longer reads every file\n\n### Changed\n\n- `dump --list` prints provider-canonical session ids \u2014 for Codex, the bare session UUID rather than the `rollout-\u2026` file basename. The listed id now round-trips into `dump --session <id>` (the old basename never matched exact or prefix); scripts parsing `--list --json` should expect the new `id` form\n\n## [0.24.4] - 2026-07-25\n\n### Fixed\n\n- The dashboard loaded persisted project data exactly once at startup and never again, so tasks, notes, decisions, and plans written by the VS Code extension or a second terminal never appeared until the dashboard was restarted\n- Load and watcher failures were swallowed into empty catch blocks. A failed load was replaced with an all-zero object and both watcher error handlers were empty, producing a dashboard indistinguishable from a genuinely quiet project\n- `sidekick dashboard` without a TTY rendered Ink's \"Raw mode is not supported\" panel into the middle of a partial frame and exited 0, so callers read the failure as success. It now fails with a message naming which stream is not a TTY, suggests a command that works when piped, and exits 1\n- Mouse tracking escape sequences were written to stdout with no TTY check, polluting redirected output\n- A bare `sidekick` printed full help to stderr with exit 1, breaking `sidekick | less` and any script checking the exit code. It now writes to stdout and exits 0\n- `sidekick --help` and `sidekick --version` made a network request and created `~/.config/sidekick/accounts/` before printing anything, because the startup side effects ran at module scope\n- `sidekick --no-color` was rejected as an unknown option, even though chalk already honored it, `NO_COLOR`, and a non-TTY stdout\n- Printing help for a bare invocation ran before Commander parsed the argv, which skipped its validation too: `sidekick --provider bogus` and `sidekick --project` (missing its value) exited 0 with help instead of reporting the error. Help for a bare or flag-only invocation is now a root action handler, so `sidekick | less` still works without disarming the option checks, and `sidekick bogus` still reports an unknown command\n- Switching to a pending session was impossible from the Plans panel: it bound `s` with no condition, so the panel's handler fired whenever an item was selected, which on Plans is always. The Sessions panel shadowed the global session filter on its Mind Map tab the same way\n- When the item list shrank under the cursor \u2014 live event churn, or typing into the filter \u2014 the detail tab and scroll position jumped back to the top of the first tab\n- The detail tab bar could highlight a tab whose content was not being rendered\n- The detail pane could render empty beneath a \"\u25B2 (N more)\" indicator. The scroll offset survives a list shrinking under the cursor, so it can outlive the content it was measured against; it is now clamped to whatever content it lands on\n- On the splash screen, panel digits 1 and 2 did nothing while 3 through 8 entered the dashboard\n- Only the newest toast was rendered, so a quota alert landing next to a context compaction showed one message and silently dropped the other\n- `parseBlessedTags.test.tsx` had never run: the vitest include glob was `*.test.ts`, which does not match `.test.tsx`. That is 15 tests covering the tag parser every rendered string flows through\n- `vitest.config.ts` declared `define` nested under `test`, where Vitest ignores it, so the `__CLI_VERSION__` injection its comment describes was inert and the next test importing `cli.ts` or `StatusBar.tsx` would have failed on a `ReferenceError`\n- `sidekick extract -i --json` silently ignored `--json`; it is now rejected, and `extract -i` degrades to plain output when not attached to a terminal\n\n### Added\n\n- `R` refreshes persisted project data on demand, and data auto-refreshes every 15 seconds. The refresh is gated by a content fingerprint, so an unchanged project schedules no re-render at all. Plan progress is part of that fingerprint: a plan record is replaced in place and keeps its `createdAt` with no `completedAt` while it runs, so a timestamp-only signature could not see steps advancing and `R` would report \"Project data is up to date\" against a stale Plans panel\n- A status-bar badge for data health, covering load failures, watcher errors, in-flight refreshes, and staleness. A watcher error expires from the badge 60 seconds after the last failure, matching the watcher's own treatment of these errors as recoverable \u2014 it closes the handle and degrades to catch-up polling \u2014 so one transient hiccup cannot latch the badge for the life of the process and hide the staleness signal behind it\n- Toasts stack up to three\n- `R`, `p`, and `s` are listed in the help overlay; `p` and `s` were previously documented only in the README\n\n### Changed\n\n- The Plans panel's source filter moved from `s` to `S`, and the Sessions panel's mind-map node filter from `f` to `F`, so the reserved global session-switch and session-filter keys work from every panel\n- The pricing cache follows `SIDEKICK_CONFIG_DIR` rather than a hardcoded `~/.config/sidekick`\n\n### Removed\n\n- The dead ANSI mind-map renderer and its helpers, and the unused `getRandomPhraseColored()`\n\n## [0.24.3] - 2026-07-24\n\n### Fixed\n\n- Dashboard costs for Claude Sonnet 5 ran 50% high, billed at $3/$15 instead of its actual $2/$10. Sonnet 5 is the `balanced` tier for the Claude API and OpenCode providers, so this shifted most totals shown before the pricing catalog was fetched\n- Dashboard costs for GPT-5.6 Luna ran about 5\xD7 high until the pricing catalog was fetched, because Luna had no rate of its own and fell back to GPT-5.6 Sol's $5/$30 rather than its published $1/$6. GPT-5.5 Pro, GPT-5.4 Pro, and GPT-5.4 Nano shared the cause and are corrected too\n- Twelve more models drew their cost from a similar model's rate. Mini and nano tiers read far too expensive (GPT-5 Nano 25\xD7 high, GPT-4.1 Nano 20\xD7) and pro tiers far too cheap (GPT-5 Pro, GPT-5.2 Pro, o1-pro, o3-pro, and o3-deep-research all showed their base model's rate). GPT-5.3 Codex and o1-mini were on outdated rates\n- GPT-5.6 Luna sizes its context gauge from an explicit 1,050,000-token window, still superseded by the window Codex reports for your tier\n\n## [0.24.2] - 2026-07-24\n\n### Added\n\n- Context windows previously reported by a provider are loaded at startup and applied to historical views, so a Codex session shows the window its account tier actually gets rather than the model's published maximum. Local read, offline-safe, non-blocking\n- Context windows also hydrate from the LiteLLM catalog, so newly released models size correctly without a CLI update\n\n### Fixed\n\n- The context gauge read roughly eight times fuller than reality on Claude Sonnet 4.7, which resolved to a 128K window against its real 1M. Sonnet 4 was affected by the same cause\n\n## [0.24.1] - 2026-07-22\n\n### Changed\n\n- Session reads inherit the shared transcript provenance surface: entrypoint, meta/sidechain flags, original roles, cwd, and git branch flow through canonical transcripts\n\n## [0.24.0] - 2026-07-22\n\n### Changed\n\n- Session reads inherit the shared discriminated event contract, normalized usage pricing, canonical transcripts, and isolated observed-session collection surface\n- A provider-reported $0 session cost now displays as $0 rather than a catalog estimate\n\n## [0.23.1] - 2026-07-21\n\n### Security\n\n- Clipboard and URL-opening helpers spawn platform tools with argument arrays instead of interpolated shell strings\n\n### Fixed\n\n- **2026-07 review backlog (CLI portion)**: quota-failure text wraps instead of rendering one character per line, the `today` date filter includes today in UTC-negative timezones, mouse clicks land on the clicked row, and configured model IDs reach the inference clients instead of being squashed to `haiku`\n- Shared observed-session reads tolerate message-less summary/bookkeeping rows and retain unresolved top-level tool requests with stable fallback IDs\n\n### Changed\n\n- `sidekick quota` now exits non-zero when a requested provider's quota is unavailable (including `--all` and `--json` failure payloads), so scripts can detect failures\n- The deprecated `quota --tier` flag (part of the removed z.ai observed-traffic estimator) is no longer accepted\n\n## [0.23.0] - 2026-07-18\n\n### Added\n\n- **`sidekick statusline`** renders a warm, cache-only account/quota/burn footer without account bootstrap, pricing hydration, or quota network access\n- **Quick capture** with `tasks add`, `tasks done`, `note add`, and `decision add`, using the shared atomic merge writers\n- **`sidekick doctor` and `sidekick today`** provide cross-provider health diagnostics and a cache-only daily brief\n- **`sidekick mcp`** exposes seven read-only facts tools for quota, burn rate, context pressure, tasks, decisions, notes, and composed project context over stdio MCP\n- **Generic handoff deep links** through `handoff open --url-template`, with identifier-only placeholders and a no-open mode\n- Failure-history, quality trend, code-impact, per-model churn/cost, and compaction-ledger summaries in terminal views\n\n### Changed\n\n- The Plans pipeline is active again: live plans persist to the shared plan store and carry per-step time, token, tool, and cost analytics into the dashboard\n- Static readers use canonical symlink-aware project identity, including legacy-store fallback\n\n## [0.22.0] - 2026-07-02\n\n### Added\n\n- **Date filter mode now actually filters by date**: The dashboard's `[D]ate` filter previously fell through to plain substring matching. It now parses `today`, `yesterday`, relative windows (`12h`, `2d`, `1w`), ISO days (`YYYY-MM-DD`), and `>`/`<` prefixes (`<2d` = older than two days); unparseable expressions show the red filter error while leaving the list unfiltered, and the overlay shows a grammar hint while empty\n- **Mouse-capture toggle**: Press `M` in the dashboard (works on the splash screen too) or launch with `--no-mouse` to disable mouse tracking so terminal click-drag text selection and copy work again. The status bar shows `MOUSE OFF` while disabled; the interactive toggle persists to `cli-config.json`, the flag is per-run\n- **Scrollable help overlay**: `?` help now windows its content with `j`/`k` scrolling and \u25B2/\u25BC indicators, so nothing is clipped on short terminals\n- **Examples in `--help`**: The root command plus `quota`, `extract`, and `dump` append real invocation examples showcasing `quota --all`, `quota history`, `extract -i`, `dump --list`, and the global `--json` flag\n- **Strict option validation**: `--provider` (root, `quota`, `quota history`, `peak`), `report --theme`, `tasks --status`, and `quota --tier` now reject unknown values at parse time with the allowed choices, instead of silently coercing typos to a default. `quota history` keeps its legacy `claude-code`/`z.ai` aliases\n- **Confirmation before `account --remove`**: Both the Claude and Codex remove paths now print the resolved account and require an interactive y/N answer (default No). `-y`/`--yes` (or `--force`) skips the prompt; `--json` and non-TTY contexts require the flag and exit 1 otherwise \u2014 **unattended automation that removes accounts must add `--yes`**\n\n### Fixed\n\n- **`q` is typable in the filter box**: The quit key no longer swallows `q` while the filter overlay is open, so queries like `query` or `sqlite` work; `q` still closes the help/changelog/context-menu overlays and quits the dashboard otherwise\n- **Panel keybindings are reachable**: Panel-declared bindings now win over the shadowable global keys while their condition holds \u2014 the Sessions panel's Mind Map `f` (filter nodes) binding works when the Mind Map tab is active, falling back to the global session filter elsewhere. Reserved keys (`q ? / M j k g G h` and digits) can never be shadowed by a panel\n- **Overlays track terminal resize**: Filter, toast, context-menu, and changelog overlays reposition on resize and clamp their widths to narrow terminals; the splash `jump` hint reflects the real panel count instead of `1-5`; the Sessions summary tasks line no longer renders as `3/ completed`\n- **Detail pane wraps to the actual layout**: Word-wrap now derives from the live side-panel width (narrow/normal/wide-side/expanded) instead of assuming the default 26-column panel, fixing under-/over-wrapping in three of the four layout modes\n- **Overlay scroll clamps to content**: The `?` help and `V` changelog overlays no longer accumulate scroll past their last line \u2014 over-scrolling then reversing responds immediately, and the changelog overlay no longer shows a blank box when scrolled past the end\n\n### Changed\n\n- **Ctrl+C always quits the dashboard**, even while an overlay is open (previously it only closed the overlay)\n- **`V` (changelog) and `r` (report) are inactive on the splash screen**; `q`, `?`, `M`, and panel digits still work there\n\n## [0.21.6] - 2026-07-02\n\n### Added\n\n- **Codex reset credits in `sidekick quota`**: When Codex quota is fetched from the API (`--refresh`, or the API-first `--all` view), the Rate Limits output now includes a `Reset Credits: N available` line plus a per-credit `Expires` row (expiry timestamp and title) for each available reset grant\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.6**: Picks up `fetchCodexResetCreditsFromApi()` and the reset-credits snapshot on Codex quota state\n\n## [0.21.5] - 2026-06-30\n\n### Fixed\n\n- **`sidekick quota --all` no longer shows Codex at 0%**: Codex emits multiple rate-limit families per session (the aggregate plan quota plus per-model families like `codex_bengalfox`). A per-model family at 0% with a later reset window could mask the real plan quota in the local-data path; the aggregate family is now always preferred, so `--all` matches `--provider codex --refresh`. `quota --all` also fetches Codex API-first (with automatic local fallback), matching the live Claude/z.ai legs; the single-provider `quota --provider codex` stays local-by-default (live via `--refresh`)\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.5**: Picks up the aggregate Codex rate-limit selection\n\n## [0.21.4] - 2026-06-30\n\n### Fixed\n\n- **`sidekick quota` shows the logged-in account**: The account line now reflects the currently logged-in Claude/Codex account even after a native `claude /login` or `codex login`, instead of the stale saved registry pointer. The live Codex account is resolved once per invocation and reused across the fetch and the printed output\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.4**: Picks up the live-first active-account resolvers\n\n## [0.21.3] - 2026-06-23\n\n### Changed\n\n- **`sidekick quota` projects every provider**: Quota output is now rendered as a unified table with aligned `now` / `projected` / `resets` columns, and projected end-of-window utilization is shown for **all** providers (Claude, Codex, z.ai) \u2014 previously only Claude displayed a projection. A `\u2014` placeholder appears when a projection is unavailable, and utilization bars are clamped to 0\u2013100% so over-limit projections render cleanly. `sidekick quota --all` uses the same table for each provider section\n- **Bundled `sidekick-shared` 0.21.3**: Picks up the quota projection helpers and the bounded synchronous CLI probes\n\n### Security\n\n- **npm audit**: Bumped `esbuild` to `^0.28.1` and `vitest` to `^4.1.9` to clear reported dev-dependency advisories\n\n## [0.21.2] - 2026-06-22\n\n### Changed\n\n- **`sidekick quota --provider zai`** now renders authoritative z.ai plan utilization from z.ai's quota API (5-Hour / Weekly windows with real reset times) instead of estimating from observed OpenCode traffic, falling back to a cached snapshot when the API is unavailable. `sidekick quota --all` and `sidekick quota history --provider zai` use the same authoritative source\n- **`--tier lite|pro|max|auto`** is deprecated and no longer affects the displayed utilization\n\n## [0.21.1] - 2026-06-21\n\n### Added\n\n- **z.ai Coding Plan quota**: `sidekick quota --provider zai` derives and renders z.ai plan utilization from OpenCode traffic already on disk (5-Hour / Weekly windows with per-tier prompt budgets). `--tier lite|pro|max|auto` overrides the assumed plan tier (default `auto`). `sidekick quota --provider opencode` now auto-routes to z.ai quota when z.ai traffic is detected. `sidekick quota --all` includes the z.ai section when active\n- **z.ai quota history heatmap**: `sidekick quota history --provider zai` renders a 13-week z.ai utilization heatmap for the current workspace, alongside the existing Claude and Codex heatmaps (now also in `--all`)\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.1**: Picks up z.ai quota derivation and the OpenCode data directory resolution fix.\n\n### Limitations\n\n- z.ai quota is **estimated, not authoritative** \u2014 it reflects only the OpenCode traffic Sidekick observed on this machine/workspace (z.ai exposes no usage API) compared against provisional per-tier prompt budgets. z.ai is observed-only (no z.ai inference provider) and has no account management yet; with `--tier auto`, the tier is under-detected early in a cycle (use an explicit `--tier`); reset times are approximate unless a rate-limit error is trapped.\n\n## [0.21.0] - 2026-06-21\n\n### Added\n\n- **Account login**: `sidekick account --login` starts the provider-isolated login flow for Claude Max or Codex and saves the authenticated profile without disturbing the active account until finalization\n- **All-provider account view**: `sidekick account --provider all` lists Claude and Codex saved accounts together, including active state. JSON output returns provider-keyed account arrays and active ids\n- **Terminal account helpers**: `sidekick account --launcher <name>` creates opt-in launchers for the selected account, and `--auto-switch <pct|off>` persists the CLI auto-switch threshold preference\n- **Multi-provider quota output**: `sidekick quota --all` shows Claude and Codex quota state together \u2014 each provider degrades independently, so one provider's quota still prints even when the other is unavailable; `--all --json` emits a provider-keyed payload for automation\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.21.0**: Picks up Account Management 2.0 acquisition, switching, terminal sync, quota auto-switch, and account schema exports.\n\n## [0.20.0] - 2026-06-17\n\n### Added\n\n- **`sidekick extract`**: New one-shot command for pulling actionable assets out of recent Claude Code and Codex chats for exactly the current cwd. It extracts URLs, filesystem-validated file paths, commands the agent suggested for the user to run, and plan-mode plans. Output is grouped and colored by default, labels each item with its source agent, validates invalid `--type` and `--limit` values, preserves `inChat` and per-item provenance in `--json`, and offers `-i/--interactive` for a picker that opens URLs or copies selected paths, commands, and plans. `--provider claude-code` and `--provider codex` scope extraction to one agent; OpenCode is reported as unsupported for now\n\nThanks to [@B33pBeeps](https://github.com/B33pBeeps) (Juan Fourie) for contributing this feature in [#17](https://github.com/cesarandreslopez/sidekick-agent-hub/pull/17), adapted from his MIT-licensed [`trawl`](https://github.com/B33pBeeps/trawl) project.\n\n## [0.19.3] - 2026-06-17\n\n### Changed\n\n- **Bundled `sidekick-shared` projection contract**: The shared assistant-turn projection now exposes a v2 `timeline` array for interleaved reasoning, narration, and tool groups. This is a shared-library contract update for downstream consumers and does not change CLI behavior by itself\n\n## [0.19.2] - 2026-06-15\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.19.2**: The shared library gains a browser-safe assistant-turn projection module (`segmentAssistantTurn()`, `assistantTurnEventsFromSessionEvents()`, and mirrored Zod schemas) that segments an assistant turn into a compact Process + Answer shape, with Claude `Task` subagent refs surfaced without leaking prompt text \u2014 internal additions that don't change CLI behavior\n\n## [0.19.1] - 2026-06-09\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.19.1**: Model-ID pricing and context-window lookups (behind the dashboard's cost and context gauges) now tolerate padded or mixed-case IDs. The shared library also gains Zod boundary schemas, an `extractSessionEvents()` progress-unwrapping helper, and a `/schemas` subpath export for downstream consumers \u2014 internal additions that don't change CLI behavior\n\n## [0.19.0] - 2026-06-09\n\n### Added\n\n- **Claude Opus 4.8 & Fable 5 support**: The dashboard's context-window gauge and cost estimates recognize `claude-opus-4-8` and `claude-fable-5` (both 1M-token context; Opus 4.8: $5/$25 per MTok, Fable 5: $10/$50 per MTok) via the shared model catalog\n\n### Changed\n\n- **Codex account switching now swaps `~/.codex/auth.json`**: `sidekick account --provider codex --switch-to <id>` (and `--add`) activates the account by atomically swapping its backed-up credentials into the system `~/.codex/` home, mirroring the Claude switch pattern \u2014 codex terminals outside Sidekick pick up the switch. Profile directories become pure credential backups, with a one-time startup migration for installs created under the old `CODEX_HOME`-redirection model. The command surfaces swap warnings on add, switch, and remove: a running codex process that needs restarting, stale credentials, or OS-keyring credential storage that Sidekick cannot swap\n\n### Fixed\n\n- **Opus 4.6/4.7 cost over-estimation**: Dashed model IDs fell back to the Opus 4.0 pricing tier ($15/$75 instead of $5/$25), inflating estimated costs 3\xD7\n- **Haiku 4.5 unpriced under dashed IDs**: Costs for `claude-haiku-4-5-*` sessions could render as \"\u2014\" because no dashed static pricing key existed\n\n## [0.18.5] - 2026-06-04\n\n### Changed\n\n- **Consistent Codex transcripts**: `sidekick dashboard` and `sidekick report` now parse Codex sessions via `parseTranscriptFromEvents()`, matching the canonical `SessionEvent` pipeline used by the other providers\n- **Bundled `sidekick-shared` 0.18.5**: Picks up the new session context evidence snapshot API (`buildSessionContextSnapshot`, `readSessionContextSnapshot`, `SessionContextSnapshot` and related types) and the Codex session evidence gap closures \u2014 `system` audit events, normalized `token_count` rate limits, per-file `apply_patch` expansion, tool-emission dedupe, MCP server attribution, and the new `ProviderReaderSessionWatcher`\n\n## [0.18.4] - 2026-05-27\n\n### Added\n\n- **`sidekick peak --provider <id>`**: New flag gates peak-hours output on the session provider. When the resolved provider is not `claude-code`, the command prints a \"not applicable\" message instead of calling the upstream endpoint\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.4**: Picks up `scopePeakHoursToSessionProvider()`, `isClaudeCodeSessionProvider()`, `createPeakHoursNotApplicableState()` for peak-hours scoping, the improved Codex quota snapshot selection logic (`isPreferredQuotaHit`, `findAccountRolloutFiles`, `shouldKeepExistingSnapshot`), and the `notApplicable` field on `PeakHoursState`\n\n## [0.18.3] - 2026-05-19\n\n### Added\n\n- **`sidekick quota history`**: New subcommand that renders a 13-week GitHub-contributions-style heatmap of quota utilization for the current workspace. Flags: `--weeks <n>` (1-26, default 13), `--provider claude|codex` (default both), `--workspace <path>` (default cwd). Bucketed glyphs (`\xB7 \u2591 \u2592 \u2593 \u2588`) are color-coded by utilization band (\u22640 / <25 / <50 / <75 / \u226575), with per-provider rows and a peak / avg / unavailable-days / samples footer. Days that hit `available: false` render as a red `\xD7`. With `--json`, emits a `{ workspaceId, weeks, providers: { claude?, codex? }, generatedAt }` payload \u2014 the same shape consumed by the VS Code dashboard\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.3**: Picks up the new per-workspace quota history surface (`appendQuotaHistorySample`, `readQuotaHistoryRange`, `readQuotaHistoryDailyBuckets`, `pruneQuotaHistory`, `getWorkspaceIdFromPath`) and the optional `workspaceId` / `appendHistorySample` hooks on `CodexQuotaWatcher`\n\n## [0.18.2] - 2026-05-19\n\n### Added\n\n- **`sidekick quota --refresh`**: New flag on the `quota` command that, for Codex, explicitly refreshes from the ChatGPT usage API before falling back to local rollout data and cached snapshots. Without the flag, the Codex quota path stays fully local and makes no upstream network call\n\n### Changed\n\n- **Codex quota is local-only by default**: `sidekick quota --provider codex` now delegates to the new `resolveCodexQuota` orchestrator in `sidekick-shared`. It checks the current workspace's most recent rollout, then recent account-level rollouts under `CODEX_HOME/sessions`, then the active account's cached snapshot \u2014 no upstream network call unless `--refresh` is passed. Failure output continues to include structured `failureKind` / `httpStatus` / `retryAfterMs` fields under `--json`\n- **Bundled `sidekick-shared` 0.18.2**: Picks up the new Codex quota orchestrator (`resolveCodexQuota`, `resolveCodexQuotaFromLocalSources`, `readLatestCodexQuotaFromRollouts`, `fetchCodexQuotaFromApi`), the relaxed `CodexRateLimits` shape (nullable `resets_at` / `window_minutes`), the rate-limit-only `token_count` event emission in `JsonlSessionWatcher`, and `state_N.sqlite` discovery in `CodexDatabase` + provider auto-detect\n\n## [0.18.1] - 2026-05-08\n\n### Changed\n\n- **Shared dashboard formatting**: terminal dashboard `fmtNum()` and `formatDuration()` now delegate to `formatTokenCount()` and `formatDurationMs()` from `sidekick-shared`, keeping the existing CLI surface (uppercase `K`/`M` suffix, compact `1m5s` style) while removing forked rounding logic\n\n## [0.18.0] - 2026-05-08\n\n### Changed\n\n- **Bundled `sidekick-shared` 0.18.0**: Picks up the new provider-aware quota orchestration surface \u2014 `MultiProviderQuotaService`, `CodexQuotaWatcher`, `getActiveAccountStatus()`, `extractToolCall()`, cost-provenance helpers (`calculateCostWithProvenance`, `mergeCostSources`), and model display helpers (`shortModelName`, `getModelDisplayInfo`, `compareModelIds`, `sortModelIds`). `parseModelId()` also now recognizes legacy Claude IDs such as `claude-3-opus-20240229` and `claude-3-5-sonnet-20241022`\n- **No CLI runtime changes**: This release ships the shared library upgrade for downstream tooling alignment; `sidekick quota`, `sidekick status`, and the live dashboard keep using the existing polling path. Wiring the new orchestrator into the CLI will land in a follow-up release\n\n## [0.17.7] - 2026-04-28\n\n### Fixed\n\n- **Quota snapshot write race**: Updated the bundled `sidekick-shared` snapshot writer so concurrent `sidekick quota` / Codex session updates no longer collide on `quota-snapshots.json.tmp` or throw `ENOENT`. Failed writes now also clean up their partial temp files instead of leaving orphans in `~/.config/sidekick/`\n\n## [0.17.6] - 2026-04-19\n\n### Added\n\n- **`sidekick peak` command**: One-shot check for Claude's current peak-hours state \u2014 weekdays 13:00\u201319:00 UTC, when session limits drain faster on Free/Pro/Max/Team subscriptions. Prints a color-coded status block with a countdown to the next transition. Data comes from the public `promoclock.co/api/status` endpoint (third-party, unaffiliated with Anthropic) with a graceful fallback when unreachable. `--json` emits the full raw state\n- **Peak-hours block in `sidekick status`**: When the active provider is `claude-code`, the Claude + OpenAI health blocks are now followed by a **Claude Peak Hours** block (off-peak or in-peak, with countdown). Gated on the provider so OpenCode / Codex users don't trigger an unnecessary third-party fetch. `--json` output includes the new `peak` field\n- **Peak-hours summary in `sidekick quota`**: Claude subscription quota output now shows a **Peak** line under the 5-hour / 7-day bars \u2014 green dot off-peak, orange dot during an active peak, with a countdown to the next transition. `--json` output includes the new `peak` field\n\n## [0.17.5] - 2026-04-18\n\n### Added\n\n- **Default account bootstrap at CLI startup**: The CLI now calls `ensureDefaultAccounts()` from `sidekick-shared` at module load and awaits the result inside a Commander `preAction` hook, so the first real subcommand blocks briefly on the bootstrap while `--version` and `--help` stay instant. When a system Claude Code or Codex credential exists and no saved account is active for that provider yet, the CLI registers it as \"Default\" \u2014 `sidekick quota`, `sidekick account`, and `sidekick stats` now reflect the active account on first run without requiring an explicit `sidekick account --add` first. Idempotent, never overwrites manually saved accounts, and all errors are swallowed so startup is never blocked\n\nThanks to [@B33pBeeps](https://github.com/B33pBeeps) (Juan Fourie) for contributing this feature in [#16](https://github.com/cesarandreslopez/sidekick-agent-hub/pull/16).\n\n## [0.17.4] - 2026-04-17\n\n### Changed\n\n- **Pricing hydration import migrated to `sidekick-shared/node`**: `cli.ts` now imports `hydratePricingCatalog` from the new Node-only subpath and keeps `detectProvider` on the package root. Runtime behavior is unchanged; the split makes the CLI's import surface self-documenting (hydration is explicitly a Node API) and aligns the CLI with the shared library's new versioned public API contract\n\n## [0.17.3] - 2026-04-17\n\n### Changed\n\n- **Version sync with the VS Code extension**: Republished to keep CLI, extension, and shared-library versions aligned after a cosmetic changelog fix in 0.17.3. No CLI code changes \u2014 functionally identical to 0.17.2\n\n## [0.17.2] - 2026-04-17\n\n### Added\n\n- **LiteLLM pricing hydration on startup**: The CLI now fetches the LiteLLM pricing catalog on startup and caches to `~/.config/sidekick/pricing-catalog.json` with a 24-hour TTL, 3s timeout, and stale-cache fallback \u2014 new model prices are picked up without a CLI upgrade\n- **Expanded pricing coverage**: GPT-4o, GPT-4.1, GPT-5.x, o1, o3, and o3-mini families are now priced alongside the existing Claude entries\n- **Real-dollar Codex / Claude Code costs**: `EventAggregator` computes cost from the pricing table when the session provider doesn't report one, so `sidekick` live dashboards now show actual dollars for Codex and Claude Code sessions\n- **`stats` footer lists unpriced models**: `sidekick stats` prints any models encountered with no pricing entry so missing coverage is visible\n\n### Fixed\n\n- **Context-gauge % wrong for Opus 4.7 (1M) and other new models**: The dashboard's context gauge was dividing by 200K for Claude Opus 4.7 (native 1M), inflating the displayed %. The shared model \u2192 context-window map now includes Opus/Sonnet 4.7 (1M), GPT-5.4 (1.05M), GPT-5.3-Codex (400K), and GPT-5.3-Codex-Spark (128K). Claude Code's `[1m]` suffix is now also honored as an explicit 1M marker\n- **Silent Sonnet-priced fallback for unknown models**: Codex, GPT-5.x, and o-series rows were being rendered at Sonnet rates. Unknown-model rows now render as `\u2014` in yellow instead of inventing a dollar figure\n\n### Changed\n\n- **`historical-data.json` schema v2**: reads `priced` flag and `unpricedModelIds` from records written by the latest VS Code extension; v1 records still read correctly\n\n## [0.17.1] - 2026-04-13\n\n### Fixed\n\n- **Codex multi-home session discovery**: Provider detection now scans all candidate Codex home directories, fixing missed sessions when the managed profile home is empty but the system `~/.codex/` has activity\n\n## [0.17.0] - 2026-04-13\n\n### Added\n\n- **Multi-provider account management**: `sidekick account` now supports `--provider codex` for Codex profile management alongside Claude Code accounts\n- **Codex account lifecycle**: `--add` prepares a profile and spawns `codex login`; `--switch-to` and `--remove` accept email, label, or profile ID\n- **Quota snapshot fallback**: `sidekick quota` for Codex shows cached rate-limit snapshots when no active session exists, with \"cached from\" timestamp\n\n### Fixed\n\n- **Email normalization**: Claude account lookup normalizes email case for reliable matching\n\n## [0.16.1] - 2026-03-27\n\n### Fixed\n\n- **Dashboard provider status scoping**: The TUI now shows degraded-service notices only for the monitored provider \u2014 Claude for Claude Code sessions, OpenAI for Codex sessions, and no status banner for OpenCode\n\n## [0.16.0] - 2026-03-23\n\n### Changed\n\n- **Consistent cost formatting**: All cost displays (`stats`, `context`, Sessions panel, narrative prompt) now use shared `formatCost()` with intelligent decimal precision (4 places for < $0.01, 2 otherwise)\n- **QuotaService**: Rewritten to wrap shared `QuotaPoller` with exponential backoff instead of manual polling loop\n- **modelContext**: Now re-exports `getModelInfo` from shared library alongside `getContextWindowSize`\n\n## [0.15.2] - 2026-03-18\n\n### Fixed\n\n- **CLI help descriptions**: Updated `quota` and `status` command descriptions to reflect provider-aware behavior\n- **`sidekick quota --provider`**: Added local `--provider` option so `sidekick quota --provider codex` works naturally\n\n## [0.15.0] - 2026-03-18\n\n### Added\n\n- **OpenAI status page monitoring**: CLI dashboard now shows OpenAI API status alongside Claude API status\n- **Codex rate limits in dashboard**: Sessions panel displays Codex rate-limit data with \"Rate Limits\" header instead of \"Quota\"\n- **Provider-aware `sidekick quota` command**: Detects active provider and shows Codex rate limits, Claude subscription quota, or an informational message for OpenCode\n\n### Fixed\n\n- **QuotaService polling for Codex**: Dashboard no longer starts Claude OAuth quota polling when the active provider is Codex\n\n## [0.14.2] - 2026-03-16\n\n### Fixed\n\n- **Quota polling interval**: Reduced quota refresh from every 30 seconds to every 5 minutes to avoid unnecessary API calls\n- **SessionsPanel `detailWidth()` call**: Removed unused parameter from `detailWidth()` in the Sessions panel quota rendering\n\n## [0.14.1] - 2026-03-14\n\n### Fixed\n\n- **Per-model context window sizes**: Dashboard context gauge now shows correct utilization for Claude Opus 4.6 (1M context) and other models with non-200K windows\n\n### Changed\n\n- **Shared model context lookup**: CLI dashboard now uses the centralized `getModelContextWindowSize()` from `sidekick-shared` instead of a local duplicate map\n\n## [0.14.0] - 2026-03-12\n\n### Added\n\n- **`sidekick account` Command**: Manage Claude Code accounts from the terminal \u2014 list saved accounts, add the current account with an optional label, switch to the next or a specific account, and remove accounts. Supports `--json` output for scripting\n- **Quota Account Label**: `sidekick quota` now shows the active account email and label above the quota bars when multi-account is enabled\n- **macOS Keychain Support**: `sidekick account` and `sidekick quota` now read and write credentials via the system Keychain on macOS, fixing account switching and quota checks on Mac\n\n## [0.13.8] - 2026-03-12\n\n### Changed\n\n- **Structured quota failure output**: `sidekick quota` now renders consistent auth, rate-limit, server, network, and unexpected-failure copy from shared quota failure descriptors while preserving `--json` machine-readable output\n- **Dashboard unavailable quota rendering**: The Sessions panel now shows Claude Code quota failures inline instead of hiding the quota section whenever subscription data is unavailable\n- **Quota transition toasts**: The Ink dashboard now fires low-noise toast notifications only when Claude Code quota failure state changes, avoiding repeated alerts every polling interval\n\n## [0.13.7] - 2026-03-11\n\n### Changed\n\n- **npm README sync**: Updated the published CLI package README to reflect current OpenCode monitoring behavior, platform-specific data directories, and the `sqlite3` runtime requirement\n- **README badge cleanup**: Removed the Ask DeepWiki badge from the published CLI package README; the repo root README still keeps it\n\n## [0.13.6] - 2026-03-11\n\n### Changed\n\n- **Refreshed CLI Dashboard Wordmark**: Updated the dashboard wordmark/header styling for a cleaner splash and dashboard identity\n\n### Fixed\n\n- **OpenCode dashboard startup**: OpenCode DB-backed session discovery now resolves projects by worktree, sandboxes, and session directory instead of quietly behaving like no session exists\n- **OpenCode runtime notices**: The CLI now prints an OpenCode-only actionable notice when `opencode.db` exists but `sqlite3` is missing, blocked, or otherwise unusable in the current shell environment\n\n## [0.13.5] - 2026-03-10\n\n### Added\n\n- **`sidekick status` Command**: One-shot Claude API status check with color-coded text output and `--json` mode\n- **Dashboard Status Banner**: Status bar shows a colored `\u25CF API minor/major/critical` indicator when Claude is degraded; Sessions panel Summary tab shows an \"API Status\" section with affected components and active incident details. Polls every 60s\n\n## [0.13.4] - 2026-03-08\n\n### Fixed\n\n- **Onboarding Phrase Spam**: Splash screen and detail pane motivational phrases memoized \u2014 no longer flicker every render tick (fixes [#13](https://github.com/cesarandreslopez/sidekick-agent-hub/issues/13))\n\n### Changed\n\n- **Simplified Logo**: Replaced 6-line ASCII robot art with compact text header in splash, help, and changelog overlays\n- **Removed Dead Code**: Removed unused `getSplashContent()` and `HELP_HEADER` exports from branding module\n\n## [0.13.3] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.2] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.1] - 2026-03-04\n\n### Added\n\n- **`sidekick quota` Command**: One-shot subscription quota check showing 5-hour and 7-day utilization with color-coded progress bars and reset countdowns \u2014 supports `--json` for machine-readable output\n- **Quota Projections**: Elapsed-time projections shown in `sidekick quota` output and TUI dashboard quota section \u2014 displays projected end-of-window utilization next to current value (e.g., `40% \u2192 100%`), included in `--json` output as `projectedFiveHour` / `projectedSevenDay`\n\n## [0.13.0] - 2026-03-03\n\n_No CLI-specific changes in this release._\n\n## [0.12.10] - 2026-03-01\n\n### Added\n\n- **Events Panel** (key 7): Scrollable live event stream with colored type badges (`[USR]`, `[AST]`, `[TOOL]`, `[RES]`), timestamps, and keyword-highlighted summaries; detail tabs for full event JSON and surrounding context\n- **Charts Panel** (key 8): Tool frequency horizontal bars, event type distribution, 60-minute activity heatmap using `\u2591\u2592\u2593\u2588` intensity characters, and pattern analysis with frequency bars and template text\n- **Multi-Mode Filter**: `/` filter overlay now supports four modes \u2014 substring, fuzzy, regex, and date range \u2014 Tab cycles modes, regex mode shows red validation errors\n- **Search Term Highlighting**: Active filter terms highlighted in blue within side list items\n- **Timeline Keyword Coloring**: Event summaries in the Sessions panel Timeline tab now use semantic keyword coloring \u2014 errors red, success green, tool names cyan, file paths magenta\n\n### Removed\n\n- **Search Panel**: Removed redundant Search panel (previously key 7) \u2014 the `/` filter with multi-mode support serves the same purpose\n\n## [0.12.9] - 2026-02-28\n\n### Added\n\n- **Standalone Data Commands**: `sidekick tasks`, `sidekick decisions`, `sidekick notes`, `sidekick stats`, `sidekick handoff` for accessing project data without launching the TUI\n- **`sidekick search <query>`**: Cross-session full-text search from the terminal\n- **`sidekick context`**: Composite output of tasks, decisions, notes, and handoff for piping into other tools\n- **`--list` flag on `sidekick dump`**: Discover available session IDs before requiring `--session <id>`\n- **Search Panel**: Search panel (panel 7) wired into the TUI dashboard\n\n### Changed\n\n- **`taskMerger` utility**: Duplicate `mergeTasks` logic extracted into shared `taskMerger` utility\n- **Model constants**: Hardcoded model IDs extracted to named constants\n\n### Fixed\n\n- **`convention` icon**: Notes panel icon replaced with valid `tip` type\n- **Linux clipboard**: Now supports Wayland (`wl-copy`) and `xsel` fallbacks, with error messages instead of silent failure\n- **`provider.dispose()`**: Added to `dump` and `report` commands (prevents SQLite connection leaks)\n\n## [0.12.8] - 2026-02-28\n\n### Changed\n\n- **Dashboard UI/UX Polish**: Visual overhaul for better hierarchy, consistency, and readability\n - Splash screen and help overlay now display the robot ASCII logo\n - Toast notifications show severity icons (\u2718 error, \u26A0 warning, \u25CF info) with inner padding\n - Focused pane uses double-border for clear focus indication\n - Section dividers (`\u2500\u2500 Title \u2500\u2500\u2500\u2500`) replace bare bold headers in summary, agents, and context attribution\n - Tab bar: active tab underlined in magenta, inactive tabs dimmed, bracket syntax removed\n - Status bar: segmented layout with `\u2502` separators; keys bold, labels dim\n - Summary metrics condensed: elapsed/events/compactions on one line, tokens on one line with cache rate and cost\n - Sparklines display peak metadata annotations\n - Progress bars use blessed color tags for consistent coloring\n - Help overlay uses dot-leader alignment for all keybinding rows\n - Empty state hints per panel (e.g. \"Tasks appear as your agent works.\")\n - Session picker groups sessions by provider with section headers when multiple providers are present\n\n## [0.12.7] - 2026-02-27\n\n### Added\n\n- **HTML Session Report**: `sidekick report` command generates a self-contained HTML report and opens it in the default browser\n - Options: `--session`, `--output`, `--theme` (dark/light), `--no-open`, `--no-thinking`\n - TUI Dashboard: press `r` to generate and open an HTML report for the current session\n\n## [0.12.6] - 2026-02-26\n\n### Added\n\n- **Session Dump Command**: `sidekick dump` exports session data in text, markdown, or JSON format with `--format`, `--width`, and `--expand` options\n- **Plans Panel Re-enabled**: Plans panel restored in CLI dashboard with plan file discovery from `~/.claude/plans/`\n- **Enhanced Status Bar**: Session info display improved with richer metadata\n\n### Fixed\n\n- **Old snapshot format migration**: Restoring pre-0.12.3 session snapshots no longer shows empty timeline entries\n\n### Changed\n\n- **Phrase library moved to shared**: CLI-specific phrase formatting kept local, all phrase content now from `sidekick-shared`\n\n## [0.12.5] - 2026-02-24\n\n### Fixed\n\n- **Update check too slow to notice new versions**: Reduced npm registry cache TTL from 24 hours to 4 hours so upgrade notices appear sooner after a new release\n\n## [0.12.4] - 2026-02-24\n\n### Fixed\n\n- **Session crash on upgrade**: Fixed `d.timestamp.getTime is not a function` error when restoring tool call data from session snapshots \u2014 `Date` objects were serialized to strings by JSON but not rehydrated on restore, causing the session monitor to crash on first run after upgrading from 0.12.2 to 0.12.3\n\n## [0.12.3] - 2026-02-24\n\n### Added\n\n- **Latest-node indicator**: The most recently added node in tree and boxed mind map views is now marked with a yellow indicator\n- **Plan analytics in mind map**: Tree and boxed views now display plan progress and per-step metrics\n - Tree view: plan header shows completion stats; steps show complexity, duration, tokens, tool calls, and errors in metadata brackets\n - Box view: progress bar with completion percentage; steps show right-aligned metrics; subtitle shows step count and total duration\n- **Cross-provider plan extraction**: Shared `PlanExtractor` now handles Claude Code (EnterPlanMode/ExitPlanMode) and OpenCode (`<proposed_plan>` XML) plans \u2014 previously only Codex plans were shown\n- **Enriched plan data model**: Plan steps include duration, token count, tool call count, and error messages\n- **Phase-grouped plan display**: When a plan has phase structure, tree and boxed views group steps under phase headers with context lines from the original plan markdown\n- **Node type filter**: Press `f` on the Mind Map tab to cycle through node type filters (file, tool, task, subagent, command, plan, knowledge-note) \u2014 non-matching sections render dimmed in grey\n\n### Fixed\n\n- **Kanban board regression**: Subagent and plan-step tasks now correctly appear in the kanban board\n\n### Changed\n\n- **Plans panel temporarily disabled**: The Plans panel in the CLI dashboard is disabled until plan-mode event capture is reliably working end-to-end. Plan nodes in the mind map remain active.\n- `DashboardState` now delegates to shared `EventAggregator` instead of maintaining its own aggregation logic\n\n## [0.12.2] - 2026-02-23\n\n### Added\n\n- **Update notifications**: The dashboard now checks the npm registry for newer versions on startup and shows a yellow banner in the status bar when an update is available (e.g., `v0.13.0 available \u2014 npm i -g sidekick-agent-hub`). Results are cached for 24 hours to avoid repeated network requests.\n\n## [0.12.1] - 2026-02-23\n\n### Fixed\n\n- **VS Code integration**: Fixed exit code 127 when the extension launches the CLI dashboard on systems using nvm or volta (node binary not found when shell init is bypassed)\n\n## [0.12.0] - 2026-02-22\n\n### Added\n\n- **\"Open CLI Dashboard\" VS Code Integration**: New VS Code command `Sidekick: Open CLI Dashboard` launches the TUI dashboard in an integrated terminal\n - Install the CLI with `npm install -g sidekick-agent-hub`\n\n## [0.11.0] - 2026-02-19\n\n### Added\n\n- **Initial Release**: Full-screen TUI dashboard for monitoring agent sessions from the terminal\n - Ink-based terminal UI with panels for sessions, tasks, kanban, mind map, notes, decisions, search, files, and git diff\n - Multi-provider support: auto-detects Claude Code, OpenCode, and Codex sessions\n - Reads from `~/.config/sidekick/` \u2014 the same data files the VS Code extension writes\n - Usage: `sidekick dashboard [--project <path>] [--provider <id>]`\n"});function qxe(e,t){if(!t)return null;if(e==="regex"){try{new RegExp(t)}catch(n){return n instanceof Error?n.message:"Invalid regex"}return null}if(e==="date"){let n=mF(t);return"error"in n?n.error:null}return null}function Zxe(e,t){switch(t.type){case"SWITCH_PANEL":return{...e,activePanelIndex:t.index,selectedItemIndex:0,detailTabIndex:0,filterString:"",filterMode:"substring",filterError:null,focusTarget:"side",overlay:null,detailScrollOffset:0};case"SELECT_ITEM":return{...e,selectedItemIndex:t.index,detailTabIndex:0,detailScrollOffset:0};case"CLAMP_SELECTION":return{...e,selectedItemIndex:t.index};case"SET_DETAIL_TAB":return{...e,detailTabIndex:t.index,detailScrollOffset:0};case"CYCLE_DETAIL_TAB":{if(t.tabCount<=1)return e;let n=(e.detailTabIndex+t.direction+t.tabCount)%t.tabCount;return{...e,detailTabIndex:n,detailScrollOffset:0}}case"CYCLE_LAYOUT":{let n=["normal","expanded","wide-side"],r=n.indexOf(e.layoutMode),o=n[(r+1)%n.length];return{...e,layoutMode:o,focusTarget:o==="expanded"?"detail":e.focusTarget}}case"TOGGLE_FOCUS":return{...e,focusTarget:e.focusTarget==="side"?"detail":"side"};case"SET_FOCUS":return{...e,focusTarget:t.target};case"SET_OVERLAY":return{...e,overlay:t.overlay,contextMenuIndex:0,overlayScrollOffset:0};case"SET_FILTER":return{...e,filterString:t.value,filterError:qxe(e.filterMode,t.value)};case"CYCLE_FILTER_MODE":{let n=["substring","fuzzy","regex","date"],r=n.indexOf(e.filterMode),o=n[(r+1)%n.length];return{...e,filterMode:o,filterError:qxe(o,e.filterString)}}case"SET_FILTER_ERROR":return{...e,filterError:t.error};case"SET_SESSION_FILTER":return{...e,sessionFilter:t.filter};case"SCROLL_DETAIL":return{...e,detailScrollOffset:t.offset};case"SCROLL_DETAIL_DELTA":{let n=ux(t.totalLines,t.viewportHeight),r=Math.max(0,Math.min(e.detailScrollOffset+t.delta,n));return{...e,detailScrollOffset:r}}case"ADD_TOAST":return{...e,toasts:[...e.toasts,t.toast]};case"REMOVE_TOAST":return{...e,toasts:e.toasts.filter(n=>n.id!==t.id)};case"FIRST_EVENT":return{...e,hasReceivedEvents:!0,sessionFilter:t.sessionPrefix?{sessionPrefix:t.sessionPrefix,label:"\u25CF active session"}:null};case"CONTEXT_MENU_NAV":{if(t.itemCount===0)return e;let n=(e.contextMenuIndex+t.delta+t.itemCount)%t.itemCount;return{...e,contextMenuIndex:n}}case"CONTEXT_MENU_SELECT":return{...e,overlay:null};case"SCROLL_SIDE":{if(t.itemCount===0)return e;let n=Math.max(0,Math.min(e.selectedItemIndex+t.delta,t.itemCount-1));return{...e,selectedItemIndex:n,detailTabIndex:0,detailScrollOffset:0}}case"OVERLAY_SCROLL":return{...e,overlayScrollOffset:Math.max(0,e.overlayScrollOffset+t.delta)};case"CLAMP_OVERLAY_SCROLL":return{...e,overlayScrollOffset:Math.min(e.overlayScrollOffset,Math.max(0,t.maxOffset))};case"TOGGLE_MOUSE":return{...e,mouseEnabled:!e.mouseEnabled};case"TICK":return{...e,renderTick:e.renderTick+1};default:return e}}var Kxe,Yxe=B(()=>{"use strict";hF();u1();Kxe={activePanelIndex:0,selectedItemIndex:0,detailTabIndex:0,layoutMode:"normal",focusTarget:"side",overlay:null,filterString:"",filterMode:"substring",filterError:null,sessionFilter:null,detailScrollOffset:0,toasts:[],hasReceivedEvents:!1,contextMenuIndex:0,overlayScrollOffset:0,renderTick:0,mouseEnabled:!0}});function Vxe(e,t,n){let{state:r,dispatch:o,exit:i,panels:s,panel:c,selectedItem:l,contextActions:p,currentItemCount:h,clampedSelection:g,sideScroll:v,detailTabCount:E,detailLineCount:I,detailViewportHeight:x,addToast:_,toggleSessionFilter:T,onMouseSettingChange:M,onRefresh:$,onGenerateReport:z,onTogglePin:U,isPinned:se,pendingSessionPath:H,onSessionSwitch:ie,accountViews:oe,onAccountSwitch:W,onAccountUndo:de}=n;if(t.ctrl&&e==="c"){i();return}if(r.overlay==="filter"){if(t.escape){o({type:"SET_FILTER",value:""}),o({type:"SET_OVERLAY",overlay:null});return}if(t.return){o({type:"SET_OVERLAY",overlay:null});return}if(t.tab){o({type:"CYCLE_FILTER_MODE"});return}if(t.backspace||t.delete){o({type:"SET_FILTER",value:r.filterString.slice(0,-1)});return}if(e&&!t.ctrl&&!t.meta){o({type:"SET_FILTER",value:r.filterString+e});return}return}if(r.overlay==="context-menu"){if(t.escape||e==="q"){o({type:"SET_OVERLAY",overlay:null});return}if(e==="j"||t.downArrow){o({type:"CONTEXT_MENU_NAV",delta:1,itemCount:p.length});return}if(e==="k"||t.upArrow){o({type:"CONTEXT_MENU_NAV",delta:-1,itemCount:p.length});return}if(t.return){let be=p[r.contextMenuIndex];if(be&&l){let he=be.handler(l);typeof he=="string"&&_(he,he.toLowerCase().includes("fail")||he.toLowerCase().includes("unavailable")?"error":"info"),o({type:"CONTEXT_MENU_SELECT"})}return}let _e=p.find(be=>be.key===e);if(_e&&l){let be=_e.handler(l);typeof be=="string"&&_(be,be.toLowerCase().includes("fail")||be.toLowerCase().includes("unavailable")?"error":"info"),o({type:"CONTEXT_MENU_SELECT"})}return}if(r.overlay==="accounts"){let _e=oe??[];if(t.escape||e==="q"||e==="A"){o({type:"SET_OVERLAY",overlay:null});return}if(e==="j"||t.downArrow){o({type:"CONTEXT_MENU_NAV",delta:1,itemCount:Math.max(1,_e.length)});return}if(e==="k"||t.upArrow){o({type:"CONTEXT_MENU_NAV",delta:-1,itemCount:Math.max(1,_e.length)});return}if(t.return){let be=_e[r.contextMenuIndex];be&&W?.(be),o({type:"SET_OVERLAY",overlay:null});return}if(e==="u"){de?.(),o({type:"SET_OVERLAY",overlay:null});return}e==="a"?_("Run: sidekick accounts add","info"):e==="l"?_("Run: sidekick accounts login <name>","info"):e==="s"&&_("Run: sidekick accounts shell <name>","info");return}if(r.overlay==="help"){t.escape||e==="?"||e==="q"?o({type:"SET_OVERLAY",overlay:null}):e==="j"||t.downArrow?o({type:"OVERLAY_SCROLL",delta:1}):(e==="k"||t.upArrow)&&o({type:"OVERLAY_SCROLL",delta:-1});return}if(r.overlay==="changelog"){t.escape||e==="V"||e==="q"?o({type:"SET_OVERLAY",overlay:null}):e==="j"||t.downArrow?o({type:"OVERLAY_SCROLL",delta:1}):(e==="k"||t.upArrow)&&o({type:"OVERLAY_SCROLL",delta:-1});return}if(e==="q"){i();return}if(t.escape){if(r.filterString){o({type:"SET_FILTER",value:""});return}if(r.focusTarget==="detail"){o({type:"SET_FOCUS",target:"side"});return}return}if(e==="?"){o({type:"SET_OVERLAY",overlay:"help"});return}if(e==="A"){o({type:"SET_OVERLAY",overlay:"accounts"});let _e=(oe??[]).findIndex(be=>be.isActive);_e>0&&o({type:"CONTEXT_MENU_NAV",delta:_e,itemCount:Math.max(1,(oe??[]).length)});return}if(e==="M"){let _e=!r.mouseEnabled;o({type:"TOGGLE_MOUSE"}),_(_e?"Mouse capture on":"Mouse capture off \u2014 terminal text selection enabled","info"),M?.(_e);return}if(e==="R"){if(!$)return;$(),_("Refreshing project data\u2026","info");return}if(e==="s"&&H&&ie){ie(H);return}let ae=parseInt(e,10);if(ae>=1&&ae<=s.length){r.hasReceivedEvents||o({type:"FIRST_EVENT",sessionPrefix:""}),s[r.activePanelIndex]?.onDeactivate?.(),o({type:"SWITCH_PANEL",index:ae-1}),s[ae-1]?.onActivate?.();return}if(r.hasReceivedEvents){if(t.tab){o({type:"TOGGLE_FOCUS"});return}if(e==="/"){o({type:"SET_OVERLAY",overlay:"filter"});return}if(e&&!nXe.has(e)){let be=(c.getKeybindings?.()||[]).find(he=>he.keys.includes(e)&&(!he.condition||he.condition(l)));if(be){be.handler(l),o({type:"TICK"});return}if(l){let Ve=c.getActions().find(Ge=>Ge.key===e&&(!Ge.condition||Ge.condition(l)));if(Ve){let Ge=Ve.handler(l);typeof Ge=="string"&&_(Ge,Ge.toLowerCase().includes("fail")||Ge.toLowerCase().includes("unavailable")?"error":"info");return}}}if(e==="z"){o({type:"CYCLE_LAYOUT"});let _e=["normal","expanded","wide-side"],be=_e.indexOf(r.layoutMode),he=_e[(be+1)%_e.length];_(`Layout: ${{normal:"Normal",expanded:"Expanded","wide-side":"Wide Side"}[he]}`,"info");return}if(e==="V"){o({type:"SET_OVERLAY",overlay:"changelog"});return}if(e==="r"){z?.();return}if(e==="p"&&U){U(),_(se?"Session unpinned":"Session pinned","info");return}if(e==="f"){T();return}if(e==="x"){l&&c.getActions().length>0&&o({type:"SET_OVERLAY",overlay:"context-menu"});return}if(e==="["){o({type:"CYCLE_DETAIL_TAB",direction:-1,tabCount:E});return}if(e==="]"){o({type:"CYCLE_DETAIL_TAB",direction:1,tabCount:E});return}if(r.focusTarget==="side"){if(e==="j"||t.downArrow){g<h-1&&(o({type:"SELECT_ITEM",index:g+1}),v.selectNext());return}if(e==="k"||t.upArrow){g>0&&(o({type:"SELECT_ITEM",index:g-1}),v.selectPrev());return}if(e==="g"){o({type:"SELECT_ITEM",index:0}),v.selectFirst();return}if(e==="G"){o({type:"SELECT_ITEM",index:Math.max(0,h-1)}),v.selectLast();return}if(t.return){o({type:"SET_FOCUS",target:"detail"});return}}if(r.focusTarget==="detail"){if(e==="j"||t.downArrow){o({type:"SCROLL_DETAIL_DELTA",delta:1,totalLines:I,viewportHeight:x});return}if(e==="k"||t.upArrow){o({type:"SCROLL_DETAIL_DELTA",delta:-1,totalLines:I,viewportHeight:x});return}if(e==="h"||t.leftArrow){o({type:"SET_FOCUS",target:"side"});return}if(e==="g"){o({type:"SCROLL_DETAIL",offset:0});return}if(e==="G"){o({type:"SCROLL_DETAIL",offset:ux(I,x)});return}}}}var nXe,Jxe=B(()=>{"use strict";u1();nXe=new Set(["j","k","g","G","h","q","?","/","M","R","s","A","1","2","3","4","5","6","7","8","9"])});function Wxe(e,t,n){let r=Math.max(0,t-n);return e.slice(Math.max(0,e.length-Math.min(r,e.length)))}var Xxe=B(()=>{"use strict"});function ewe(e,t){let n=e();return{allItems:n,currentItems:t([...n])}}var twe=B(()=>{"use strict"});function SJ(e,t=3){return t<=0?[]:e.slice(Math.max(0,e.length-t))}var nwe=B(()=>{"use strict"});function rwe(){return{loadedAt:null,error:null,refreshing:!1,watcherError:null,watcherErrorAt:null}}function bJ(e,t){return e.error?{text:"\u26A0 data",color:"red"}:e.watcherError!==null&&(e.watcherErrorAt===null||t-e.watcherErrorAt<=6e4)?{text:"\u26A0 session",color:"yellow"}:e.refreshing?{text:"\u21BB",color:"gray"}:e.loadedAt!==null&&t-e.loadedAt>12e4?{text:`stale ${Math.floor((t-e.loadedAt)/6e4)}m`,color:"yellow"}:null}var IJ=B(()=>{"use strict"});function _J({panels:e,metrics:t,staticData:n,isPinned:r,pendingSessionPath:o,onSessionSwitch:i,onTogglePin:s,onGenerateReport:c,mouseInitiallyEnabled:l,onMouseSettingChange:p,onRefresh:h,dataStatus:g,notice:v,accountViews:E,onAccountSwitch:I,onAccountUndo:x}){let[_,T]=(0,Kr.useReducer)(Zxe,Kxe,Qe=>({...Qe,mouseEnabled:l!==!1})),{exit:M}=tm(),{isRawModeSupported:$}=Ka(),{columns:z,rows:U}=Ya(),se=(0,Kr.useRef)(0),H=(0,Kr.useRef)(0),ie=(0,Kr.useRef)(null),oe=(0,Kr.useRef)(!1),W=(0,Kr.useRef)(0),de=(0,Kr.useRef)(null);(0,Kr.useEffect)(()=>{if(!_.hasReceivedEvents&&t.eventCount>0){let Qe=(t.sessionStartTime||"").substring(0,8);T({type:"FIRST_EVENT",sessionPrefix:Qe})}},[t.eventCount,_.hasReceivedEvents,t.sessionStartTime]),(0,Kr.useEffect)(()=>{if(!oe.current){H.current=t.timelineAppendCount,oe.current=!0;return}if(t.timelineAppendCount!==H.current){for(let Qe of Wxe(t.timeline,t.timelineAppendCount,H.current))Qe.type==="summary"?ae(Qe.summary||"Context compacted","warning"):Qe.type==="system"&&Qe.summary?.includes("ended")&&ae(Qe.summary,"info");H.current=t.timelineAppendCount}},[t.timelineAppendCount,t.timeline]);let ae=(0,Kr.useCallback)((Qe,gt)=>{let Mt={error:4e3,warning:3e3,info:2e3},on=++se.current;T({type:"ADD_TOAST",toast:{id:on,message:Qe,severity:gt,expiresAt:Date.now()+Mt[gt]}}),setTimeout(()=>{T({type:"REMOVE_TOAST",id:on})},Mt[gt])},[]),_e=(0,Kr.useRef)(0);(0,Kr.useEffect)(()=>{v&&v.id!==_e.current&&(_e.current=v.id,ae(v.message,v.severity))},[v,ae]),(0,Kr.useEffect)(()=>{if(t.providerId!=="claude-code"){ie.current=null;return}let Qe=$f(t.quota);if(!Qe){ie.current=null;return}ie.current!==Qe.alertKey&&(ie.current=Qe.alertKey,ae(`${Qe.title}: ${Qe.message}`,Qe.severity))},[ae,t.providerId,t.quota]);let be=e[_.activePanelIndex],he=z<sXe||U<aXe,Ge=(()=>{switch(_.layoutMode){case"expanded":return 0;case"wide-side":return Math.min(cXe,z-30);default:return z<80?iXe:oXe}})(),mt=(0,Kr.useCallback)(Qe=>{let gt=Qe;if(_.sessionFilter&&["tasks","kanban","notes","decisions","plans"].includes(be.id)&&(be.id==="kanban"?gt=gt.map(Mt=>uXe(Mt,_.sessionFilter)):gt=gt.filter(Mt=>owe(Mt,_.sessionFilter))),_.filterString){let Mt=_.filterString,on=_.filterMode;if(on==="date"){let ur=mF(Mt);if(!("error"in ur)){let cn=ur.since?Date.parse(ur.since):-1/0,wo=ur.until?Date.parse(ur.until):1/0;gt=gt.filter(ko=>{let ts=be.getItemTimestamp?be.getItemTimestamp(ko):k_e(ko.data);return ts!==null&&ts>=cn&&ts<wo})}}else gt=gt.filter(ur=>{let cn=be.getSearchableText?.(ur)??ur.label.replace(/\{[^}]*\}/g,"");switch(on){case"fuzzy":{let wo=cn.toLowerCase();return Mt.toLowerCase().split(/\s+/).filter(ko=>ko).every(ko=>wo.includes(ko))}case"regex":try{return new RegExp(Mt).test(cn)}catch{return!1}default:return cn.toLowerCase().includes(Mt.toLowerCase())}})}return gt.sort((Mt,on)=>Mt.sortKey-on.sortKey),gt},[be,_.sessionFilter,_.filterString,_.filterMode]),Bt=be.viewVersion??0,{allItems:wr,currentItems:ve}=(0,Kr.useMemo)(()=>ewe(()=>be.getItems(t,n),mt),[be,Bt,t,n,mt]),ot=Math.min(_.selectedItemIndex,Math.max(0,ve.length-1));ot!==_.selectedItemIndex&&ve.length>0&&T({type:"CLAMP_SELECTION",index:ot});let Ht=Math.max(1,U-5),Yt=axe(Ht,ve.length),pn=rxe({totalItems:ve.length,viewportHeight:Yt});(0,Kr.useEffect)(()=>{pn.selectedIndex!==_.selectedItemIndex&&pn.setSelected(_.selectedItemIndex)},[_.selectedItemIndex]);let Zn=ve[ot],Rt=be.detailTabs,Vt=Math.min(_.detailTabIndex,Rt.length-1),xt=(0,Kr.useMemo)(()=>txe(),[Zn?.id,Vt]),rn=Math.max(40,z-Ge-3),it=!!_.sessionFilter,Ot=(0,Kr.useMemo)(()=>{if(Zn&&Rt.length>0&&Vt>=0){let Qe=Rt[Vt],gt=Qe.label;return(gt==="Timeline"||gt==="Mind Map"?"":xt+`
|
|
1141
1141
|
`)+Qe.render(Zn,t,n,{width:rn})}if(!Zn){let Qe=["tasks","kanban","notes","decisions","plans"].includes(be.id);return it&&Qe?"{grey-fg}No items in this session \u2014 press {/grey-fg}{magenta-fg}f{/magenta-fg}{grey-fg} to see all{/grey-fg}":"{grey-fg}(no item selected){/grey-fg}"}return""},[Zn,Rt,Vt,xt,t,n,rn,be,Bt,it]),$t=Ot.split(`
|
|
1142
1142
|
`),ft=Math.max(1,U-5),Xt=Rt[Vt];(0,Kr.useEffect)(()=>{if(!Xt?.autoScrollBottom)return;let Qe=`${be.id}:${Zn?.id??"none"}:${Vt}`;if(!($t.length<=ft)){if(sxe(Qe,de.current,$t.length,W.current)){let gt=ux($t.length,ft);T({type:"SCROLL_DETAIL",offset:gt})}de.current=Qe,W.current=$t.length}},[$t.length,Xt?.autoScrollBottom,ft,be.id,Zn?.id,Vt]),"activeDetailTabIndex"in be&&(be.activeDetailTabIndex=_.detailTabIndex);let Ir=(0,Kr.useCallback)(()=>Zn?be.getActions().filter(Qe=>!Qe.condition||Qe.condition(Zn)):[],[be,Zn]),so=_.overlay==="context-menu"?Ir():[],ht=(0,Kr.useCallback)(()=>{let Qe=[],gt=be.getKeybindings?.()||[];for(let Mt of gt)(!Mt.condition||Mt.condition(Zn))&&Qe.push(`${Mt.keys[0]} ${Mt.label.toLowerCase().substring(0,12)}`);return be.getActions().length>0&&_.focusTarget==="side"&&Qe.push("x actions"),["tasks","kanban","notes","decisions","plans"].includes(be.id)&&_.focusTarget==="side"&&Qe.push("f session"),Qe.length>0?Qe.join(" ")+" ":""},[be,Zn,_.focusTarget]),Yr=(0,Kr.useCallback)(()=>{if(_.sessionFilter){T({type:"SET_SESSION_FILTER",filter:null}),ae("Session filter cleared","info");return}let Qe;if(e[_.activePanelIndex].id==="sessions")Qe=Zn?.data;else{let Mt=e.find(on=>on.id==="sessions");Mt&&(Qe=Mt.getItems(t,n).find(ur=>ur.id==="active")?.data)}if(!Qe){ae("No session selected","info");return}let gt=Qe;if(gt.type==="active"){let Mt=(gt.metrics?.sessionStartTime||"").substring(0,8);if(!Mt){ae("No session start time available","info");return}let on={sessionPrefix:Mt,label:"\u25CF active session"};T({type:"SET_SESSION_FILTER",filter:on}),ae(`Session filter: ${on.label}`,"info")}else if(gt.type==="historical"&>.session){let Mt={date:gt.session.date,label:`\u229B ${gt.session.date}`};T({type:"SET_SESSION_FILTER",filter:Mt}),ae(`Session filter: ${Mt.label}`,"info")}else ae("Cannot filter by this item","info")},[_.sessionFilter,_.activePanelIndex,Zn,e,t,n,ae]),Lo=(0,Kr.useCallback)(Qe=>{if(_.overlay){Qe.type==="click"&&T({type:"SET_OVERLAY",overlay:null});return}if(!_.hasReceivedEvents)return;let{x:gt,y:Mt}=Qe;if(Qe.type==="scroll"){if(gt<Ge&&Ge>0){let on=Qe.scrollDirection==="down"?3:-3;T({type:"SCROLL_SIDE",delta:on,itemCount:ve.length});let ur=Math.max(0,Math.min(ot+on,ve.length-1));pn.setSelected(ur)}else{let on=Qe.scrollDirection==="down"?3:-3;T({type:"SCROLL_DETAIL_DELTA",delta:on,totalLines:$t.length,viewportHeight:ft})}return}if(!(Qe.type!=="click"||Qe.button!=="left")){if(Mt===0){let on=cxe(gt,e);on!==null&&(e[_.activePanelIndex]?.onDeactivate?.(),T({type:"SWITCH_PANEL",index:on}),e[on]?.onActivate?.());return}if(!(Mt>=U-1)){if(gt<Ge&&Ge>0){T({type:"SET_FOCUS",target:"side"});let on=lxe(Mt,pn.scrollOffset,ve.length);on!==null&&(T({type:"SELECT_ITEM",index:on}),pn.setSelected(on))}else if(T({type:"SET_FOCUS",target:"detail"}),Mt===1&&Rt.length>1){let on=uxe(gt,Ge,Rt.map(ur=>ur.label),Vt);if(on!==null){T({type:"SET_DETAIL_TAB",index:on});return}}}}},[_.overlay,_.hasReceivedEvents,_.activePanelIndex,Ge,ve.length,ot,pn,$t.length,ft,e,Rt,U]);Cd((Qe,gt)=>Vxe(Qe,gt,{state:_,dispatch:T,exit:M,panels:e,panel:be,selectedItem:Zn,contextActions:so,currentItemCount:ve.length,clampedSelection:ot,sideScroll:pn,detailTabCount:Rt.length,detailLineCount:$t.length,detailViewportHeight:ft,addToast:ae,toggleSessionFilter:Yr,onMouseSettingChange:p,onRefresh:h,onGenerateReport:c,onTogglePin:s,isPinned:r,pendingSessionPath:o,onSessionSwitch:i,accountViews:E,onAccountSwitch:I,onAccountUndo:x}),{isActive:$});let Ur=(0,Kr.useMemo)(()=>{let Qe=(E??[]).find(Mt=>Mt.isActive&&Mt.providerId===(/codex/i.test(t.providerName??"")?"codex":"claude-code"))??(E??[]).find(Mt=>Mt.isActive);if(!Qe)return null;let gt=Qe.health.state==="fresh"?"green":Qe.health.state==="expiring"?"yellow":Qe.health.state==="expired"||Qe.health.state==="missing"?"red":"gray";return{label:Qe.label??Qe.email??Qe.id,color:gt}},[E,t.providerName]);return he?(0,Oo.jsx)(Nxe,{columns:z,rows:U}):_.hasReceivedEvents?(0,Oo.jsx)(BF,{onMouse:Lo,enabled:_.mouseEnabled,children:(0,Oo.jsxs)(Ze,{flexDirection:"column",height:U,width:z,children:[_.overlay!=="help"&&_.overlay!=="changelog"&&(0,Oo.jsx)(fxe,{panels:e,activeIndex:_.activePanelIndex,layoutMode:_.layoutMode}),_.overlay!=="help"&&_.overlay!=="changelog"&&(0,Oo.jsxs)(Ze,{flexGrow:1,flexDirection:"row",children:[Ge>0&&(0,Oo.jsx)(mxe,{items:ve,selectedIndex:ot,scrollOffset:pn.scrollOffset,focused:_.focusTarget==="side",width:Ge,viewportHeight:Yt,panelTitle:be.title,sessionFilterActive:!!_.sessionFilter&&["tasks","kanban","notes","decisions","plans"].includes(be.id),emptyStateHint:be.emptyStateHint,filterString:_.filterString}),(0,Oo.jsxs)(Ze,{flexDirection:"column",flexGrow:1,children:[(0,Oo.jsx)(gxe,{tabs:Rt,activeIndex:Vt}),(0,Oo.jsx)(yxe,{content:Ot,scrollOffset:_.detailScrollOffset,viewportHeight:ft,focused:_.focusTarget==="detail"})]})]}),_.overlay==="help"&&(0,Oo.jsx)(wxe,{panels:e,activePanelIndex:_.activePanelIndex,scrollOffset:_.overlayScrollOffset,onClampScroll:Qe=>T({type:"CLAMP_OVERLAY_SCROLL",maxOffset:Qe})}),_.overlay==="changelog"&&(0,Oo.jsx)(Qxe,{entries:rXe,scrollOffset:_.overlayScrollOffset,onClampScroll:Qe=>T({type:"CLAMP_OVERLAY_SCROLL",maxOffset:Qe})}),(0,Oo.jsx)(mJ,{eventCount:t.eventCount,providerName:t.providerName,permissionMode:t.permissionMode,focusTarget:_.focusTarget,panelHints:ht(),sessionFilter:_.sessionFilter?.label??null,filterString:_.filterString,matchCount:ve.length,totalCount:wr.length,updateInfo:t.updateInfo,providerStatus:t.providerStatus,openaiStatus:t.openaiStatus,dataBadge:g?bJ(g,Date.now()):null,mouseEnabled:_.mouseEnabled,activeAccount:Ur}),_.overlay==="context-menu"&&(0,Oo.jsx)(Dxe,{actions:so,selectedIndex:_.contextMenuIndex}),_.overlay==="accounts"&&(0,Oo.jsx)(gJ,{views:E??[],selectedIndex:_.contextMenuIndex}),_.overlay==="filter"&&(0,Oo.jsx)(Rxe,{filterString:_.filterString,filterMode:_.filterMode,filterError:_.filterError}),_.toasts.length>0&&SJ(_.toasts).map((Qe,gt)=>(0,Oo.jsx)(AJ,{toast:Qe,row:gt},Qe.id))]})}):(0,Oo.jsx)(BF,{onMouse:Lo,enabled:_.mouseEnabled,children:(0,Oo.jsxs)(Ze,{flexDirection:"column",height:U,width:z,children:[(0,Oo.jsx)(Ze,{flexGrow:1,justifyContent:"center",alignItems:"center",children:(0,Oo.jsx)(_xe,{panelCount:e.length})}),(0,Oo.jsx)(mJ,{eventCount:0,focusTarget:"side",panelHints:"",sessionFilter:null,filterString:"",mouseEnabled:_.mouseEnabled,dataBadge:g?bJ(g,Date.now()):null,activeAccount:Ur}),_.overlay==="accounts"&&(0,Oo.jsx)(gJ,{views:E??[],selectedIndex:_.contextMenuIndex}),_.toasts.length>0&&SJ(_.toasts).map((Qe,gt)=>(0,Oo.jsx)(AJ,{toast:Qe,row:gt},Qe.id))]})})}function owe(e,t){let n=e.data;if(!n)return!1;if(t.sessionPrefix){let r=n.sessionOrigin,o=n.sessionId;return r?.substring(0,8)===t.sessionPrefix||o?.substring(0,8)===t.sessionPrefix||!r&&!o}if(t.date){let r=n.createdAt,o=n.timestamp,i=n.sessionOrigin,s=n.sessionId;return!!(r?.startsWith(t.date)||o?.startsWith(t.date)||i?.startsWith(t.date)||s?.startsWith(t.date))}return!0}function uXe(e,t){let n=e.data,r=n.tasks.filter(l=>owe({id:"",label:"",sortKey:0,data:l},t)),o={pending:"{yellow-fg}\u25CB{/yellow-fg}",in_progress:"{green-fg}\u2192{/green-fg}",completed:"{cyan-fg}\u2713{/cyan-fg}"},i={pending:"Pending",in_progress:"Active",completed:"Completed"},s=o[n.status]||"",c=i[n.status]||n.status;return{...e,label:`${s} ${c} (${r.length})`,data:{status:n.status,tasks:r}}}var Kr,Oo,rXe,oXe,iXe,sXe,aXe,cXe,iwe=B(async()=>{"use strict";Kr=Me(fn(),1);await ii();nxe();Gh();oxe();u1();dxe();await pxe();await hxe();await Axe();await vxe();await Cxe();await xxe();await kxe();await Txe();await Bxe();await $xe();await Oxe();await Pxe();await zxe();await EJ();Hxe();Pt();Yxe();Jxe();hF();Xxe();twe();nwe();IJ();Oo=Me(On(),1),rXe=Nq(Gxe,5),oXe=26,iXe=22,sXe=60,aXe=15,cXe=40});function lXe(e){return e.map(t=>`${t.status}:${t.completionRate}:${t.steps.map(n=>n.status).join("")}`).join(",")}function RF(e,...t){let n="";for(let r of e)for(let o of t){let i=r[o];typeof i=="string"&&i>n&&(n=i)}return n}function swe(e){return[e.tasks.length,RF(e.tasks,"updatedAt","createdAt"),e.notes.length,RF(e.notes,"updatedAt","createdAt"),e.decisions.length,RF(e.decisions,"timestamp"),e.plans.length,RF(e.plans,"completedAt","createdAt"),lXe(e.plans),e.sessions.length,e.totalTokens,e.totalCost,e.totalSessions].join("|")}var awe=B(()=>{"use strict"});function cwe(e,t,n,r){if(!n||n===e.id)return e;let o=t.find(i=>i.id===n);return e.dispose(),o??r(n)}function uwe(e,t,n=r=>process.exit(r)){return()=>{e(),t(),n(0)}}var lwe=B(()=>{"use strict"});var mwe={};hn(mwe,{dashboardAction:()=>pXe,getProviderRuntimeIssue:()=>$F,inferPlanStatus:()=>pwe,persistPlan:()=>l1});import*as Hf from"path";import*as fwe from"os";import*as rm from"fs";function dwe(e){switch(e){case"opencode":return new If;case"codex":return new da;default:return new dl}}function $F(e){if(e.id!=="opencode")return null;let t=e.getRuntimeStatus?.();if(!t||t.available||t.kind==="db_missing")return null;let n=t.message?` ${t.message}`:"",r=t.kind==="sqlite_missing"?" Recommendation: install `sqlite3`, ensure it is on PATH for the current shell, then retry.":t.kind==="sqlite_blocked"?" Recommendation: ensure `sqlite3` is executable in the same environment as this shell, then retry.":" Recommendation: verify `sqlite3` can read `opencode.db` in the current environment, then retry.";return`${e.displayName} session database is unavailable.${n}${r}`}function pwe(e){return e.steps.some(t=>t.status==="failed")?"failed":e.steps.some(t=>t.status==="pending"||t.status==="in_progress")?"in_progress":e.steps.some(t=>t.status==="completed")?"completed":"abandoned"}function dXe(e){return{id:e.id,description:e.description,status:e.status,phase:e.phase,complexity:e.complexity,startedAt:e.startedAt,completedAt:e.completedAt,durationMs:e.durationMs,tokensUsed:e.tokensUsed,toolCalls:e.toolCalls,errorMessage:e.errorMessage,costUsd:e.costUsd}}async function l1(e,t){let n=e.getMetrics(),r=n.plan,o=n.sessionId;if(!r||!o||r.steps.length===0&&!r.rawMarkdown)return;let i=xr(t),s=await AT(i.canonicalSlug),c=r.steps.map(dXe),l=c.filter(g=>g.status==="completed").length,p={id:`${o}:${r.title}`,projectSlug:i.canonicalSlug,sessionId:o,title:r.title||"Plan",source:r.source??"claude-code",createdAt:r.enteredAt??new Date().toISOString(),completedAt:r.exitedAt,status:pwe(r),steps:c,completionRate:c.length>0?l/c.length:0,totalDurationMs:r.totalDurationMs,totalTokensUsed:c.reduce((g,v)=>g+(v.tokensUsed??0),0)||void 0,totalToolCalls:c.reduce((g,v)=>g+(v.toolCalls??0),0)||void 0,totalCostUsd:c.reduce((g,v)=>g+(v.costUsd??0),0)||void 0,rawMarkdown:r.rawMarkdown},h=s.filter(g=>!(g.sessionId===o&&g.title===p.title));await J9(i.canonicalSlug,[p,...h])}function fXe(){return{sessions:[],tasks:[],decisions:[],notes:[],plans:[],totalTokens:0,totalCost:0,totalSessions:0}}async function pXe(e,t){let n=hC(mC(),"dashboard","sidekick dump --format text or sidekick today");if(n){process.stderr.write(n.message),process.exitCode=n.exitCode;return}let r=t.parent.opts(),o=t.opts(),i=Wi(r),s=r.project||process.cwd(),c=o.session,l=!!o.replay,p=i,h=$F(i),v=TT().filter(me=>me!==i.id).map(me=>dwe(me));if(!c){let me=h?[]:i.findAllSessions(s),De=v.filter(dt=>!$F(dt));if(me.length>0||De.some(dt=>dt.findAllSessions(s).length>0))try{let dt=h&&De[0]||i,Jt=h?De.slice(1):De,An=await X_e(dt,s,Jt);An.sessionPath&&(c=Hf.basename(An.sessionPath,Hf.extname(An.sessionPath)),l=!0,An.providerId&&An.providerId!==i.id&&(p=cwe(i,v,An.providerId,dwe)))}catch{for(let dt of v)dt.dispose();process.exit(0)}else if(h){for(let dt of v)dt.dispose();console.error(h),process.exitCode=1;return}}for(let me of v)me!==p&&me.dispose();let E=$F(p);if(E){console.error(E),process.exitCode=1;return}let I=!1,x=!1,_=fXe(),T="",M=!1,$=rwe(),z=0,U=null;function se(me,De){U={id:++z,message:me,severity:De},cn()}async function H(me){if(!(M||x)){M=!0,$.refreshing=!0,me!=="auto"&&cn();try{let De=await FIe(s),Je=swe(De);$.error=null,$.loadedAt=Date.now(),Je!==T?(T=Je,_=De,me==="manual"&&se("Project data refreshed","info")):me==="manual"&&se("Project data is up to date","info")}catch(De){$.error=De instanceof Error?De.message:String(De),me!=="auto"&&se(`Could not load project data: ${$.error}`,"error")}finally{M=!1,$.refreshing=!1,cn()}}}let ie=0,oe=6e4;function W(me){let De=me instanceof Error?me.message:String(me),Je=Date.now();$.watcherError=De,$.watcherErrorAt=Je,Je-ie>oe&&(ie=Je,se(`Session read error: ${De}`,"error")),cn()}await H("initial"),$.error&&se(`Project data unavailable: ${$.error}`,"error");let de=new sF,ae=new gF(s,p.id),_e=[ae,new yF,new vF,new CF,new EF,new SF,new bF,new IF];ae.onNarrativeComplete=()=>cn();let be=new aF,he=new cF(p.id),Ve=new uF;Ve.onResult(me=>{me&&(de.setUpdateInfo(me),cn())});let Ge=null,mt=p.findAllSessions(s);Ge=mt.length>0?mt[0]:null;let Bt=!1,wr=null;function ve(){if(x||!Y||!Q?.getPosition)return;let me=Date.now();if(me-Ne<=tt)return;let De=0;try{De=rm.statSync(Y).size}catch{}de.persistSnapshot(Q.getPosition(),De),Ne=me}function ot(me){if(Q?.getPosition&&Y){let Je=0;try{Je=rm.statSync(Y).size}catch{}de.persistSnapshot(Q.getPosition(),Je)}try{Q?.stop()}catch{}l1(de,s).catch(()=>{}),de.reset(),wr=null;let De=Hf.basename(me,Hf.extname(me));de.setSessionId(De);try{let Je=zI({provider:p,workspacePath:s,sessionId:De,callbacks:{onEvent:Jt=>{x||(de.processEvent(Jt),Jt.type==="system"&&Jt.summary==="Session ended"&&l1(de,s).catch(()=>{}),cn())},onError:Jt=>W(Jt),onBatchComplete:ve,onReset:()=>{x||(de.resetSessionEvents(),cn())}}});Q=Je.watcher,Y=Je.sessionPath;let dt=!1;if(Q.seekTo){let Jt=0;try{Jt=rm.statSync(Y).size}catch{}let An=de.tryRestoreFromSnapshot(De,p.id,Jt);An!==null&&(Q.seekTo(An),dt=!0)}if(Q.start(!0),de.markHistoryReplayed(p.id),!dt&&Q.getPosition){let Jt=0;try{Jt=rm.statSync(Y).size}catch{}de.persistSnapshot(Q.getPosition(),Jt),Ne=Date.now()}}catch{}Ge=me,Rt(),cn()}let Ht=15e3,Yt=2e3,pn=3e4,Zn=setInterval(()=>{H("auto"),Rt()},Ht);function Rt(){x||!Y||(de.setSubagentStats(E0(p,Y)),cn())}function Vt(){try{let me=p.findAllSessions(s);if(me.length===0)return;let De=me[0];De!==Ge&&(Bt?(wr=De,cn()):ot(De),Ge=De)}catch{}}let xt=new pT({sources:[H9(p,s,{observationOnly:!0})]}),rn=xt.subscribe(me=>{if(x)return;me.changes.some(Je=>Je.type!=="removed"&&Je.reference.sourceKey!==Y)&&Vt()},{debounceMs:Yt,pollIntervalMs:pn}),{render:it}=await ii().then(()=>i1),Ot=o.mouse===!1?!1:qye().mouseEnabled??!0,$t=me=>{try{Zye({mouseEnabled:me})}catch{}},ft=()=>{if(!Y)return;let{metrics:me,transcript:De,subagents:Je}=aT(p,Y),dt=FI(me,De,{subagents:Je,sessionFileName:Hf.basename(Y),includeThinking:!0,includeToolDetail:!0,theme:"dark"}),Jt=Hf.join(fwe.tmpdir(),`sidekick-report-${Date.now()}.html`);rm.writeFileSync(Jt,dt,"utf-8"),UI(Jt)},Xt=null,Ir=null;function so(){let me=de.getMetrics();return(me!==Xt||!Ir)&&(Xt=me,Ir={...me,...GIe(p.id,me.providerStatus,me.openaiStatus)}),Ir}let ht=[],Yr=()=>{try{ht=Dc()}catch{ht=[]}};Yr();let Lo=tB(()=>{Yr(),cn()}),Ur=me=>{Th(me.providerId,me.id).then(De=>{let Je=pB(De,Ga(me));se(Je.headline,Je.ok?"info":"error");for(let dt of Je.warnings.slice(0,2))se(dt,"warning");Yr(),cn()})},Qe=()=>{let me=["claude-code","codex"].filter(Je=>ZT(Je));if(me.length===0){se("There is no account switch to undo.","info"),cn();return}if(me.length>1){se("Both providers have a switch to undo; run `sidekick accounts undo --provider \u2026`.","info"),cn();return}let De=me[0];KT(De).then(Je=>{let dt=ht.find(An=>An.id===Je.accountId),Jt=pB(Je,dt?Ga(dt):Je.accountId);se(Jt.ok?`Undo: ${Jt.headline}`:Jt.headline,Jt.ok?"info":"error"),Yr(),cn()})},gt=null;if(pC().accounts?.keepAlive){let me=()=>{VT().then(De=>{De.refreshed.length&&se(`Keep-alive refreshed ${De.refreshed.length} inactive account${De.refreshed.length===1?"":"s"}.`,"info");for(let Je of De.failed)se(`Keep-alive: ${ms[Je.providerId]} ${Je.id} \u2014 ${Je.error}`,"warning");Yr(),cn()})};setTimeout(me,5e3).unref?.(),gt=setInterval(me,3600*1e3),gt.unref?.()}let Mt=()=>({panels:_e,metrics:so(),staticData:_,isPinned:Bt,pendingSessionPath:wr,onSessionSwitch:ot,onTogglePin:()=>{Bt=!Bt,cn()},onGenerateReport:ft,onRefresh:()=>{H("manual")},dataStatus:{...$},notice:U,mouseInitiallyEnabled:Ot,onMouseSettingChange:$t,accountViews:ht,onAccountSwitch:Ur,onAccountUndo:Qe}),on=it(xJ.default.createElement(_J,Mt()));I=!0;let ur=null;function cn(){!I||ur||(ur=setTimeout(()=>{ur=null,on.rerender(xJ.default.createElement(_J,Mt()))},100))}let wo={};be.onUpdate(me=>{de.setQuota(me),ko();let De=vK(me,cP,wo);wo=De.memory;for(let Je of De.alerts)se(CK(Je),Je.severity==="critical"?"error":"warning");cn()});function ko(){try{let me=de.getMetrics(),De=ml(void 0,{selfHeal:!1}),Je=p.id,dt=Je==="codex"&&De.codex.present?{providerId:"codex",id:De.codex.accountId??null,label:De.codex.label??null}:De.claude.present?{providerId:"claude-code",id:De.claude.accountId??null,label:De.claude.label??null}:null,Jt=B0(me.quota),An=me.quota?.providerId??Je,Pc=me.sessionStartTime?Date.parse(me.sessionStartTime):NaN;xI({writer:"cli-dashboard",account:dt,quota:{claude:An==="claude-code"?Jt:null,codex:An==="codex"?Jt:null},context:{usedPercentage:me.context.percent,contextWindowSize:me.context.limit||null,totalInputTokens:me.tokens.input+me.tokens.cacheRead+me.tokens.cacheWrite,totalOutputTokens:me.tokens.output,totalTokens:me.sessionTokens.combined.total},session:{sessionId:me.sessionId??null,cwd:s,model:me.currentModel??null,costUsd:me.tokens.cost,durationMs:Number.isFinite(Pc)?Math.max(0,Date.now()-Pc):null,linesAdded:null,linesRemoved:null,promptCacheHitRatio:null},billingBlock:$N(me.billingBlock)})}catch{}}let ts=6e4,$s=!1;async function Pi(){if(!$s){$s=!0;try{let me=new Date,De=await $0({providers:[p],since:new Date(me.getTime()-2*R0),until:me});de.setBillingBlock(fT(dT(De.events,{now:me}))),ko(),cn()}catch{}finally{$s=!1}}}Pi();let Vr=setInterval(()=>{Pi()},ts);Vr.unref?.(),he.onUpdate(me=>{de.setProviderStatus(me),cn()}),he.onOpenAIUpdate(me=>{de.setOpenAIStatus(me),cn()});function ba(){if(!x){x=!0,l1(de,s).catch(()=>{});try{rn.dispose(),xt.dispose()}catch{}try{clearInterval(Zn)}catch{}try{clearInterval(Vr)}catch{}try{be.stop()}catch{}try{Lo.dispose(),gt&&clearInterval(gt)}catch{}try{he.stop()}catch{}try{Q?.stop()}catch{}try{p.dispose()}catch{}for(let me of _e)me.dispose?.()}}process.on("exit",()=>dx());let ns=uwe(ba,()=>on.unmount());process.once("SIGINT",ns),process.once("SIGTERM",ns);let Q=null,Y,we=!1;c&&de.setSessionId(c);let Ne=0,tt=3e4;try{let me=zI({provider:p,workspacePath:s,sessionId:c,callbacks:{onEvent:De=>{x||(de.processEvent(De),De.type==="system"&&De.summary==="Session ended"&&l1(de,s).catch(()=>{}),cn())},onError:De=>W(De),onBatchComplete:ve,onReset:()=>{x||(de.resetSessionEvents(),cn())}}});if(Q=me.watcher,Y=me.sessionPath,!c&&Y&&(c=Hf.basename(Y,Hf.extname(Y)),de.setSessionId(c)),c&&l&&Q.seekTo){let De=0;try{De=rm.statSync(Y).size}catch{}let Je=de.tryRestoreFromSnapshot(c,p.id,De);Je!==null&&(Q.seekTo(Je),we=!0)}}catch{}if(p.id==="claude-code"&&be.start(),he.start(),Ve.check(),cn(),Q){if(we){if(Q.start(!0),Q.getPosition&&Y){let me=0;try{me=rm.statSync(Y).size}catch{}de.persistSnapshot(Q.getPosition(),me),Ne=Date.now()}}else if(Q.start(l),l&&de.markHistoryReplayed(p.id),l&&Q.getPosition&&Y){let me=0;try{me=rm.statSync(Y).size}catch{}de.persistSnapshot(Q.getPosition(),me),Ne=Date.now()}Rt()}await on.waitUntilExit(),process.removeListener("SIGINT",ns),process.removeListener("SIGTERM",ns),ba(),process.exit(0)}var xJ,hwe=B(async()=>{"use strict";xJ=Me(fn(),1);Pt();Pt();Cl();zIe();UIe();jIe();HIe();qIe();KIe();T_e();B_e();R_e();$_e();M_e();F_e();L_e();j_e();await exe();await iwe();await EJ();RP();o7();gC();awe();IJ();lwe()});function gwe(e){if(e==null)return"";let t=typeof e=="number"&&!Number.isFinite(e)?"":String(e);return/[",\r\n]/.test(t)?`"${t.replace(/"/g,'""')}"`:t}function bd(e,t){let n=[t.map(r=>gwe(r.header)).join(",")];for(let r of e)n.push(t.map(o=>gwe(o.value(r))).join(","));return n.join(`
|
|
1143
1143
|
`)+`
|
|
@@ -1277,7 +1277,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
1277
1277
|
depsCount: ${t},
|
|
1278
1278
|
deps: ${n}}`};var Umt={keyword:"dependencies",type:"object",schemaType:"object",error:gm.error,code(e){let[t,n]=Lmt(e);JMe(e,t),WMe(e,n)}};function Lmt({schema:e}){let t={},n={};for(let r in e){if(r==="__proto__")continue;let o=Array.isArray(e[r])?t:n;o[r]=e[r]}return[t,n]}function JMe(e,t=e.schema){let{gen:n,data:r,it:o}=e;if(Object.keys(t).length===0)return;let i=n.let("missing");for(let s in t){let c=t[s];if(c.length===0)continue;let l=(0,YR.propertyInData)(n,r,s,o.opts.ownProperties);e.setParams({property:s,depsCount:c.length,deps:c.join(", ")}),o.allErrors?n.if(l,()=>{for(let p of c)(0,YR.checkReportMissingProp)(e,p)}):(n.if((0,noe._)`${l} && (${(0,YR.checkMissingProp)(e,c,i)})`),(0,YR.reportMissingProp)(e,i),n.else())}}gm.validatePropertyDeps=JMe;function WMe(e,t=e.schema){let{gen:n,data:r,keyword:o,it:i}=e,s=n.name("valid");for(let c in t)(0,Fmt.alwaysValidSchema)(i,t[c])||(n.if((0,YR.propertyInData)(n,r,c,i.opts.ownProperties),()=>{let l=e.subschema({keyword:o,schemaProp:c},s);e.mergeValidEvaluated(l,s)},()=>n.var(s,!0)),e.ok(s))}gm.validateSchemaDeps=WMe;gm.default=Umt});var tQe=ne(roe=>{"use strict";Object.defineProperty(roe,"__esModule",{value:!0});var eQe=Rn(),jmt=Ar(),Hmt={message:"property name must be valid",params:({params:e})=>(0,eQe._)`{propertyName: ${e.propertyName}}`},Gmt={keyword:"propertyNames",type:"object",schemaType:["object","boolean"],error:Hmt,code(e){let{gen:t,schema:n,data:r,it:o}=e;if((0,jmt.alwaysValidSchema)(o,n))return;let i=t.name("valid");t.forIn("key",r,s=>{e.setParams({propertyName:s}),e.subschema({keyword:"propertyNames",data:s,dataTypes:["string"],propertyName:s,compositeRule:!0},i),t.if((0,eQe.not)(i),()=>{e.error(!0),o.allErrors||t.break()})}),e.ok(i)}};roe.default=Gmt});var ioe=ne(ooe=>{"use strict";Object.defineProperty(ooe,"__esModule",{value:!0});var ej=Qd(),rp=Rn(),qmt=ag(),tj=Ar(),Zmt={message:"must NOT have additional properties",params:({params:e})=>(0,rp._)`{additionalProperty: ${e.additionalProperty}}`},Kmt={keyword:"additionalProperties",type:["object"],schemaType:["boolean","object"],allowUndefined:!0,trackErrors:!0,error:Zmt,code(e){let{gen:t,schema:n,parentSchema:r,data:o,errsCount:i,it:s}=e;if(!i)throw new Error("ajv implementation error");let{allErrors:c,opts:l}=s;if(s.props=!0,l.removeAdditional!=="all"&&(0,tj.alwaysValidSchema)(s,n))return;let p=(0,ej.allSchemaProperties)(r.properties),h=(0,ej.allSchemaProperties)(r.patternProperties);g(),e.ok((0,rp._)`${i} === ${qmt.default.errors}`);function g(){t.forIn("key",o,_=>{!p.length&&!h.length?I(_):t.if(v(_),()=>I(_))})}function v(_){let T;if(p.length>8){let M=(0,tj.schemaRefOrVal)(s,r.properties,"properties");T=(0,ej.isOwnProperty)(t,M,_)}else p.length?T=(0,rp.or)(...p.map(M=>(0,rp._)`${_} === ${M}`)):T=rp.nil;return h.length&&(T=(0,rp.or)(T,...h.map(M=>(0,rp._)`${(0,ej.usePattern)(e,M)}.test(${_})`))),(0,rp.not)(T)}function E(_){t.code((0,rp._)`delete ${o}[${_}]`)}function I(_){if(l.removeAdditional==="all"||l.removeAdditional&&n===!1){E(_);return}if(n===!1){e.setParams({additionalProperty:_}),e.error(),c||t.break();return}if(typeof n=="object"&&!(0,tj.alwaysValidSchema)(s,n)){let T=t.name("valid");l.removeAdditional==="failing"?(x(_,T,!1),t.if((0,rp.not)(T),()=>{e.reset(),E(_)})):(x(_,T),c||t.if((0,rp.not)(T),()=>t.break()))}}function x(_,T,M){let $={keyword:"additionalProperties",dataProp:_,dataPropType:tj.Type.Str};M===!1&&Object.assign($,{compositeRule:!0,createErrors:!1,allErrors:!1}),e.subschema($,T)}}};ooe.default=Kmt});var oQe=ne(aoe=>{"use strict";Object.defineProperty(aoe,"__esModule",{value:!0});var Ymt=OR(),nQe=Qd(),soe=Ar(),rQe=ioe(),Vmt={keyword:"properties",type:"object",schemaType:"object",code(e){let{gen:t,schema:n,parentSchema:r,data:o,it:i}=e;i.opts.removeAdditional==="all"&&r.additionalProperties===void 0&&rQe.default.code(new Ymt.KeywordCxt(i,rQe.default,"additionalProperties"));let s=(0,nQe.allSchemaProperties)(n);for(let g of s)i.definedProperties.add(g);i.opts.unevaluated&&s.length&&i.props!==!0&&(i.props=soe.mergeEvaluated.props(t,(0,soe.toHash)(s),i.props));let c=s.filter(g=>!(0,soe.alwaysValidSchema)(i,n[g]));if(c.length===0)return;let l=t.name("valid");for(let g of c)p(g)?h(g):(t.if((0,nQe.propertyInData)(t,o,g,i.opts.ownProperties)),h(g),i.allErrors||t.else().var(l,!0),t.endIf()),e.it.definedProperties.add(g),e.ok(l);function p(g){return i.opts.useDefaults&&!i.compositeRule&&n[g].default!==void 0}function h(g){e.subschema({keyword:"properties",schemaProp:g,dataProp:g},l)}}};aoe.default=Vmt});var cQe=ne(coe=>{"use strict";Object.defineProperty(coe,"__esModule",{value:!0});var iQe=Qd(),nj=Rn(),sQe=Ar(),aQe=Ar(),Jmt={keyword:"patternProperties",type:"object",schemaType:"object",code(e){let{gen:t,schema:n,data:r,parentSchema:o,it:i}=e,{opts:s}=i,c=(0,iQe.allSchemaProperties)(n),l=c.filter(x=>(0,sQe.alwaysValidSchema)(i,n[x]));if(c.length===0||l.length===c.length&&(!i.opts.unevaluated||i.props===!0))return;let p=s.strictSchema&&!s.allowMatchingProperties&&o.properties,h=t.name("valid");i.props!==!0&&!(i.props instanceof nj.Name)&&(i.props=(0,aQe.evaluatedPropsToName)(t,i.props));let{props:g}=i;v();function v(){for(let x of c)p&&E(x),i.allErrors?I(x):(t.var(h,!0),I(x),t.if(h))}function E(x){for(let _ in p)new RegExp(x).test(_)&&(0,sQe.checkStrictMode)(i,`property ${_} matches pattern ${x} (use allowMatchingProperties)`)}function I(x){t.forIn("key",r,_=>{t.if((0,nj._)`${(0,iQe.usePattern)(e,x)}.test(${_})`,()=>{let T=l.includes(x);T||e.subschema({keyword:"patternProperties",schemaProp:x,dataProp:_,dataPropType:aQe.Type.Str},h),i.opts.unevaluated&&g!==!0?t.assign((0,nj._)`${g}[${_}]`,!0):!T&&!i.allErrors&&t.if((0,nj.not)(h),()=>t.break())})})}}};coe.default=Jmt});var uQe=ne(uoe=>{"use strict";Object.defineProperty(uoe,"__esModule",{value:!0});var Wmt=Ar(),Xmt={keyword:"not",schemaType:["object","boolean"],trackErrors:!0,code(e){let{gen:t,schema:n,it:r}=e;if((0,Wmt.alwaysValidSchema)(r,n)){e.fail();return}let o=t.name("valid");e.subschema({keyword:"not",compositeRule:!0,createErrors:!1,allErrors:!1},o),e.failResult(o,()=>e.reset(),()=>e.error())},error:{message:"must NOT be valid"}};uoe.default=Xmt});var lQe=ne(loe=>{"use strict";Object.defineProperty(loe,"__esModule",{value:!0});var eht=Qd(),tht={keyword:"anyOf",schemaType:"array",trackErrors:!0,code:eht.validateUnion,error:{message:"must match a schema in anyOf"}};loe.default=tht});var dQe=ne(doe=>{"use strict";Object.defineProperty(doe,"__esModule",{value:!0});var rj=Rn(),nht=Ar(),rht={message:"must match exactly one schema in oneOf",params:({params:e})=>(0,rj._)`{passingSchemas: ${e.passing}}`},oht={keyword:"oneOf",schemaType:"array",trackErrors:!0,error:rht,code(e){let{gen:t,schema:n,parentSchema:r,it:o}=e;if(!Array.isArray(n))throw new Error("ajv implementation error");if(o.opts.discriminator&&r.discriminator)return;let i=n,s=t.let("valid",!1),c=t.let("passing",null),l=t.name("_valid");e.setParams({passing:c}),t.block(p),e.result(s,()=>e.reset(),()=>e.error(!0));function p(){i.forEach((h,g)=>{let v;(0,nht.alwaysValidSchema)(o,h)?t.var(l,!0):v=e.subschema({keyword:"oneOf",schemaProp:g,compositeRule:!0},l),g>0&&t.if((0,rj._)`${l} && ${s}`).assign(s,!1).assign(c,(0,rj._)`[${c}, ${g}]`).else(),t.if(l,()=>{t.assign(s,!0),t.assign(c,g),v&&e.mergeEvaluated(v,rj.Name)})})}}};doe.default=oht});var fQe=ne(foe=>{"use strict";Object.defineProperty(foe,"__esModule",{value:!0});var iht=Ar(),sht={keyword:"allOf",schemaType:"array",code(e){let{gen:t,schema:n,it:r}=e;if(!Array.isArray(n))throw new Error("ajv implementation error");let o=t.name("valid");n.forEach((i,s)=>{if((0,iht.alwaysValidSchema)(r,i))return;let c=e.subschema({keyword:"allOf",schemaProp:s},o);e.ok(o),e.mergeEvaluated(c)})}};foe.default=sht});var hQe=ne(poe=>{"use strict";Object.defineProperty(poe,"__esModule",{value:!0});var oj=Rn(),mQe=Ar(),aht={message:({params:e})=>(0,oj.str)`must match "${e.ifClause}" schema`,params:({params:e})=>(0,oj._)`{failingKeyword: ${e.ifClause}}`},cht={keyword:"if",schemaType:["object","boolean"],trackErrors:!0,error:aht,code(e){let{gen:t,parentSchema:n,it:r}=e;n.then===void 0&&n.else===void 0&&(0,mQe.checkStrictMode)(r,'"if" without "then" and "else" is ignored');let o=pQe(r,"then"),i=pQe(r,"else");if(!o&&!i)return;let s=t.let("valid",!0),c=t.name("_valid");if(l(),e.reset(),o&&i){let h=t.let("ifClause");e.setParams({ifClause:h}),t.if(c,p("then",h),p("else",h))}else o?t.if(c,p("then")):t.if((0,oj.not)(c),p("else"));e.pass(s,()=>e.error(!0));function l(){let h=e.subschema({keyword:"if",compositeRule:!0,createErrors:!1,allErrors:!1},c);e.mergeEvaluated(h)}function p(h,g){return()=>{let v=e.subschema({keyword:h},c);t.assign(s,c),e.mergeValidEvaluated(v,s),g?t.assign(g,(0,oj._)`${h}`):e.setParams({ifClause:h})}}}};function pQe(e,t){let n=e.schema[t];return n!==void 0&&!(0,mQe.alwaysValidSchema)(e,n)}poe.default=cht});var gQe=ne(moe=>{"use strict";Object.defineProperty(moe,"__esModule",{value:!0});var uht=Ar(),lht={keyword:["then","else"],schemaType:["object","boolean"],code({keyword:e,parentSchema:t,it:n}){t.if===void 0&&(0,uht.checkStrictMode)(n,`"${e}" without "if" is ignored`)}};moe.default=lht});var AQe=ne(hoe=>{"use strict";Object.defineProperty(hoe,"__esModule",{value:!0});var dht=Jre(),fht=ZMe(),pht=Wre(),mht=YMe(),hht=VMe(),ght=XMe(),Aht=tQe(),yht=ioe(),vht=oQe(),Cht=cQe(),Eht=uQe(),Sht=lQe(),bht=dQe(),Iht=fQe(),_ht=hQe(),xht=gQe();function wht(e=!1){let t=[Eht.default,Sht.default,bht.default,Iht.default,_ht.default,xht.default,Aht.default,yht.default,ght.default,vht.default,Cht.default];return e?t.push(fht.default,mht.default):t.push(dht.default,pht.default),t.push(hht.default),t}hoe.default=wht});var yQe=ne(goe=>{"use strict";Object.defineProperty(goe,"__esModule",{value:!0});var es=Rn(),kht={message:({schemaCode:e})=>(0,es.str)`must match format "${e}"`,params:({schemaCode:e})=>(0,es._)`{format: ${e}}`},Dht={keyword:"format",type:["number","string"],schemaType:"string",$data:!0,error:kht,code(e,t){let{gen:n,data:r,$data:o,schema:i,schemaCode:s,it:c}=e,{opts:l,errSchemaPath:p,schemaEnv:h,self:g}=c;if(!l.validateFormats)return;o?v():E();function v(){let I=n.scopeValue("formats",{ref:g.formats,code:l.code.formats}),x=n.const("fDef",(0,es._)`${I}[${s}]`),_=n.let("fType"),T=n.let("format");n.if((0,es._)`typeof ${x} == "object" && !(${x} instanceof RegExp)`,()=>n.assign(_,(0,es._)`${x}.type || "string"`).assign(T,(0,es._)`${x}.validate`),()=>n.assign(_,(0,es._)`"string"`).assign(T,x)),e.fail$data((0,es.or)(M(),$()));function M(){return l.strictSchema===!1?es.nil:(0,es._)`${s} && !${T}`}function $(){let z=h.$async?(0,es._)`(${x}.async ? await ${T}(${r}) : ${T}(${r}))`:(0,es._)`${T}(${r})`,U=(0,es._)`(typeof ${T} == "function" ? ${z} : ${T}.test(${r}))`;return(0,es._)`${T} && ${T} !== true && ${_} === ${t} && !${U}`}}function E(){let I=g.formats[i];if(!I){M();return}if(I===!0)return;let[x,_,T]=$(I);x===t&&e.pass(z());function M(){if(l.strictSchema===!1){g.logger.warn(U());return}throw new Error(U());function U(){return`unknown format "${i}" ignored in schema at path "${p}"`}}function $(U){let se=U instanceof RegExp?(0,es.regexpCode)(U):l.code.formats?(0,es._)`${l.code.formats}${(0,es.getProperty)(i)}`:void 0,H=n.scopeValue("formats",{key:i,ref:U,code:se});return typeof U=="object"&&!(U instanceof RegExp)?[U.type||"string",U.validate,(0,es._)`${H}.validate`]:["string",U,H]}function z(){if(typeof I=="object"&&!(I instanceof RegExp)&&I.async){if(!h.$async)throw new Error("async format in sync schema");return(0,es._)`await ${T}(${r})`}return typeof _=="function"?(0,es._)`${T}(${r})`:(0,es._)`${T}.test(${r})`}}}};goe.default=Dht});var vQe=ne(Aoe=>{"use strict";Object.defineProperty(Aoe,"__esModule",{value:!0});var Tht=yQe(),Bht=[Tht.default];Aoe.default=Bht});var CQe=ne(aw=>{"use strict";Object.defineProperty(aw,"__esModule",{value:!0});aw.contentVocabulary=aw.metadataVocabulary=void 0;aw.metadataVocabulary=["title","description","default","deprecated","readOnly","writeOnly","examples"];aw.contentVocabulary=["contentMediaType","contentEncoding","contentSchema"]});var SQe=ne(yoe=>{"use strict";Object.defineProperty(yoe,"__esModule",{value:!0});var Rht=DMe(),$ht=jMe(),Mht=AQe(),Qht=vQe(),EQe=CQe(),Oht=[Rht.default,$ht.default,(0,Mht.default)(),Qht.default,EQe.metadataVocabulary,EQe.contentVocabulary];yoe.default=Oht});var IQe=ne(ij=>{"use strict";Object.defineProperty(ij,"__esModule",{value:!0});ij.DiscrError=void 0;var bQe;(function(e){e.Tag="tag",e.Mapping="mapping"})(bQe||(ij.DiscrError=bQe={}))});var xQe=ne(Coe=>{"use strict";Object.defineProperty(Coe,"__esModule",{value:!0});var cw=Rn(),voe=IQe(),_Qe=GL(),Nht=NR(),Pht=Ar(),zht={message:({params:{discrError:e,tagName:t}})=>e===voe.DiscrError.Tag?`tag "${t}" must be string`:`value of tag "${t}" must be in oneOf`,params:({params:{discrError:e,tag:t,tagName:n}})=>(0,cw._)`{error: ${e}, tag: ${n}, tagValue: ${t}}`},Fht={keyword:"discriminator",type:"object",schemaType:"object",error:zht,code(e){let{gen:t,data:n,schema:r,parentSchema:o,it:i}=e,{oneOf:s}=o;if(!i.opts.discriminator)throw new Error("discriminator: requires discriminator option");let c=r.propertyName;if(typeof c!="string")throw new Error("discriminator: requires propertyName");if(r.mapping)throw new Error("discriminator: mapping is not supported");if(!s)throw new Error("discriminator: requires oneOf keyword");let l=t.let("valid",!1),p=t.const("tag",(0,cw._)`${n}${(0,cw.getProperty)(c)}`);t.if((0,cw._)`typeof ${p} == "string"`,()=>h(),()=>e.error(!1,{discrError:voe.DiscrError.Tag,tag:p,tagName:c})),e.ok(l);function h(){let E=v();t.if(!1);for(let I in E)t.elseIf((0,cw._)`${p} === ${I}`),t.assign(l,g(E[I]));t.else(),e.error(!1,{discrError:voe.DiscrError.Mapping,tag:p,tagName:c}),t.endIf()}function g(E){let I=t.name("valid"),x=e.subschema({keyword:"oneOf",schemaProp:E},I);return e.mergeEvaluated(x,cw.Name),I}function v(){var E;let I={},x=T(o),_=!0;for(let z=0;z<s.length;z++){let U=s[z];if(U?.$ref&&!(0,Pht.schemaHasRulesButRef)(U,i.self.RULES)){let H=U.$ref;if(U=_Qe.resolveRef.call(i.self,i.schemaEnv.root,i.baseId,H),U instanceof _Qe.SchemaEnv&&(U=U.schema),U===void 0)throw new Nht.default(i.opts.uriResolver,i.baseId,H)}let se=(E=U?.properties)===null||E===void 0?void 0:E[c];if(typeof se!="object")throw new Error(`discriminator: oneOf subschemas (or referenced schemas) must have "properties/${c}"`);_=_&&(x||T(U)),M(se,z)}if(!_)throw new Error(`discriminator: "${c}" must be required`);return I;function T({required:z}){return Array.isArray(z)&&z.includes(c)}function M(z,U){if(z.const)$(z.const,U);else if(z.enum)for(let se of z.enum)$(se,U);else throw new Error(`discriminator: "properties/${c}" must have "const" or "enum"`)}function $(z,U){if(typeof z!="string"||z in I)throw new Error(`discriminator: "${c}" values must be unique strings`);I[z]=U}}}};Coe.default=Fht});var wQe=ne((t9t,Uht)=>{Uht.exports={$schema:"http://json-schema.org/draft-07/schema#",$id:"http://json-schema.org/draft-07/schema#",title:"Core schema meta-schema",definitions:{schemaArray:{type:"array",minItems:1,items:{$ref:"#"}},nonNegativeInteger:{type:"integer",minimum:0},nonNegativeIntegerDefault0:{allOf:[{$ref:"#/definitions/nonNegativeInteger"},{default:0}]},simpleTypes:{enum:["array","boolean","integer","null","number","object","string"]},stringArray:{type:"array",items:{type:"string"},uniqueItems:!0,default:[]}},type:["object","boolean"],properties:{$id:{type:"string",format:"uri-reference"},$schema:{type:"string",format:"uri"},$ref:{type:"string",format:"uri-reference"},$comment:{type:"string"},title:{type:"string"},description:{type:"string"},default:!0,readOnly:{type:"boolean",default:!1},examples:{type:"array",items:!0},multipleOf:{type:"number",exclusiveMinimum:0},maximum:{type:"number"},exclusiveMaximum:{type:"number"},minimum:{type:"number"},exclusiveMinimum:{type:"number"},maxLength:{$ref:"#/definitions/nonNegativeInteger"},minLength:{$ref:"#/definitions/nonNegativeIntegerDefault0"},pattern:{type:"string",format:"regex"},additionalItems:{$ref:"#"},items:{anyOf:[{$ref:"#"},{$ref:"#/definitions/schemaArray"}],default:!0},maxItems:{$ref:"#/definitions/nonNegativeInteger"},minItems:{$ref:"#/definitions/nonNegativeIntegerDefault0"},uniqueItems:{type:"boolean",default:!1},contains:{$ref:"#"},maxProperties:{$ref:"#/definitions/nonNegativeInteger"},minProperties:{$ref:"#/definitions/nonNegativeIntegerDefault0"},required:{$ref:"#/definitions/stringArray"},additionalProperties:{$ref:"#"},definitions:{type:"object",additionalProperties:{$ref:"#"},default:{}},properties:{type:"object",additionalProperties:{$ref:"#"},default:{}},patternProperties:{type:"object",additionalProperties:{$ref:"#"},propertyNames:{format:"regex"},default:{}},dependencies:{type:"object",additionalProperties:{anyOf:[{$ref:"#"},{$ref:"#/definitions/stringArray"}]}},propertyNames:{$ref:"#"},const:!0,enum:{type:"array",items:!0,minItems:1,uniqueItems:!0},type:{anyOf:[{$ref:"#/definitions/simpleTypes"},{type:"array",items:{$ref:"#/definitions/simpleTypes"},minItems:1,uniqueItems:!0}]},format:{type:"string"},contentMediaType:{type:"string"},contentEncoding:{type:"string"},if:{$ref:"#"},then:{$ref:"#"},else:{$ref:"#"},allOf:{$ref:"#/definitions/schemaArray"},anyOf:{$ref:"#/definitions/schemaArray"},oneOf:{$ref:"#/definitions/schemaArray"},not:{$ref:"#"}},default:!0}});var DQe=ne((Uo,Eoe)=>{"use strict";Object.defineProperty(Uo,"__esModule",{value:!0});Uo.MissingRefError=Uo.ValidationError=Uo.CodeGen=Uo.Name=Uo.nil=Uo.stringify=Uo.str=Uo._=Uo.KeywordCxt=Uo.Ajv=void 0;var Lht=bMe(),jht=SQe(),Hht=xQe(),kQe=wQe(),Ght=["/properties"],sj="http://json-schema.org/draft-07/schema",uw=class extends Lht.default{_addVocabularies(){super._addVocabularies(),jht.default.forEach(t=>this.addVocabulary(t)),this.opts.discriminator&&this.addKeyword(Hht.default)}_addDefaultMetaSchema(){if(super._addDefaultMetaSchema(),!this.opts.meta)return;let t=this.opts.$data?this.$dataMetaSchema(kQe,Ght):kQe;this.addMetaSchema(t,sj,!1),this.refs["http://json-schema.org/schema"]=sj}defaultMeta(){return this.opts.defaultMeta=super.defaultMeta()||(this.getSchema(sj)?sj:void 0)}};Uo.Ajv=uw;Eoe.exports=Uo=uw;Eoe.exports.Ajv=uw;Object.defineProperty(Uo,"__esModule",{value:!0});Uo.default=uw;var qht=OR();Object.defineProperty(Uo,"KeywordCxt",{enumerable:!0,get:function(){return qht.KeywordCxt}});var lw=Rn();Object.defineProperty(Uo,"_",{enumerable:!0,get:function(){return lw._}});Object.defineProperty(Uo,"str",{enumerable:!0,get:function(){return lw.str}});Object.defineProperty(Uo,"stringify",{enumerable:!0,get:function(){return lw.stringify}});Object.defineProperty(Uo,"nil",{enumerable:!0,get:function(){return lw.nil}});Object.defineProperty(Uo,"Name",{enumerable:!0,get:function(){return lw.Name}});Object.defineProperty(Uo,"CodeGen",{enumerable:!0,get:function(){return lw.CodeGen}});var Zht=jL();Object.defineProperty(Uo,"ValidationError",{enumerable:!0,get:function(){return Zht.default}});var Kht=NR();Object.defineProperty(Uo,"MissingRefError",{enumerable:!0,get:function(){return Kht.default}})});var TQe=ne(dw=>{"use strict";Object.defineProperty(dw,"__esModule",{value:!0});dw.formatLimitDefinition=void 0;var Yht=DQe(),op=Rn(),jy=op.operators,aj={formatMaximum:{okStr:"<=",ok:jy.LTE,fail:jy.GT},formatMinimum:{okStr:">=",ok:jy.GTE,fail:jy.LT},formatExclusiveMaximum:{okStr:"<",ok:jy.LT,fail:jy.GTE},formatExclusiveMinimum:{okStr:">",ok:jy.GT,fail:jy.LTE}},Vht={message:({keyword:e,schemaCode:t})=>(0,op.str)`should be ${aj[e].okStr} ${t}`,params:({keyword:e,schemaCode:t})=>(0,op._)`{comparison: ${aj[e].okStr}, limit: ${t}}`};dw.formatLimitDefinition={keyword:Object.keys(aj),type:"string",schemaType:"string",$data:!0,error:Vht,code(e){let{gen:t,data:n,schemaCode:r,keyword:o,it:i}=e,{opts:s,self:c}=i;if(!s.validateFormats)return;let l=new Yht.KeywordCxt(i,c.RULES.all.format.definition,"format");l.$data?p():h();function p(){let v=t.scopeValue("formats",{ref:c.formats,code:s.code.formats}),E=t.const("fmt",(0,op._)`${v}[${l.schemaCode}]`);e.fail$data((0,op.or)((0,op._)`typeof ${E} != "object"`,(0,op._)`${E} instanceof RegExp`,(0,op._)`typeof ${E}.compare != "function"`,g(E)))}function h(){let v=l.schema,E=c.formats[v];if(!E||E===!0)return;if(typeof E!="object"||E instanceof RegExp||typeof E.compare!="function")throw new Error(`"${o}": format "${v}" does not define "compare" function`);let I=t.scopeValue("formats",{key:v,ref:E,code:s.code.formats?(0,op._)`${s.code.formats}${(0,op.getProperty)(v)}`:void 0});e.fail$data(g(I))}function g(v){return(0,op._)`${v}.compare(${n}, ${r}) ${aj[o].fail} 0`}},dependencies:["format"]};var Jht=e=>(e.addKeyword(dw.formatLimitDefinition),e);dw.default=Jht});var MQe=ne((VR,$Qe)=>{"use strict";Object.defineProperty(VR,"__esModule",{value:!0});var fw=h$e(),Wht=TQe(),Soe=Rn(),BQe=new Soe.Name("fullFormats"),Xht=new Soe.Name("fastFormats"),boe=(e,t={keywords:!0})=>{if(Array.isArray(t))return RQe(e,t,fw.fullFormats,BQe),e;let[n,r]=t.mode==="fast"?[fw.fastFormats,Xht]:[fw.fullFormats,BQe],o=t.formats||fw.formatNames;return RQe(e,o,n,r),t.keywords&&(0,Wht.default)(e),e};boe.get=(e,t="full")=>{let r=(t==="fast"?fw.fastFormats:fw.fullFormats)[e];if(!r)throw new Error(`Unknown format "${e}"`);return r};function RQe(e,t,n,r){var o,i;(o=(i=e.opts.code).formats)!==null&&o!==void 0||(i.formats=(0,Soe._)`require("ajv-formats/dist/formats").${r}`);for(let s of t)e.addFormat(s,n[s])}$Qe.exports=VR=boe;Object.defineProperty(VR,"__esModule",{value:!0});VR.default=boe});function egt(){let e=new QQe.default({strict:!1,validateFormats:!0,validateSchema:!1,allErrors:!0});return(0,OQe.default)(e),e}var QQe,OQe,cj,NQe=B(()=>{QQe=Me(a$e(),1),OQe=Me(MQe(),1);cj=class{constructor(t){this._ajv=t??egt()}getValidator(t){let n="$id"in t&&typeof t.$id=="string"?this._ajv.getSchema(t.$id)??this._ajv.compile(t):this._ajv.compile(t);return r=>n(r)?{valid:!0,data:r,errorMessage:void 0}:{valid:!1,data:void 0,errorMessage:this._ajv.errorsText(n.errors)}}}});var uj,PQe=B(()=>{$x();uj=class{constructor(t){this._server=t}requestStream(t,n,r){return this._server.requestStream(t,n,r)}createMessageStream(t,n){let r=this._server.getClientCapabilities();if((t.tools||t.toolChoice)&&!r?.sampling?.tools)throw new Error("Client does not support sampling tools capability.");if(t.messages.length>0){let o=t.messages[t.messages.length-1],i=Array.isArray(o.content)?o.content:[o.content],s=i.some(h=>h.type==="tool_result"),c=t.messages.length>1?t.messages[t.messages.length-2]:void 0,l=c?Array.isArray(c.content)?c.content:[c.content]:[],p=l.some(h=>h.type==="tool_use");if(s){if(i.some(h=>h.type!=="tool_result"))throw new Error("The last message must contain only tool_result content if any is present");if(!p)throw new Error("tool_result blocks are not matching any tool_use from the previous message")}if(p){let h=new Set(l.filter(v=>v.type==="tool_use").map(v=>v.id)),g=new Set(i.filter(v=>v.type==="tool_result").map(v=>v.toolUseId));if(h.size!==g.size||![...h].every(v=>g.has(v)))throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}return this.requestStream({method:"sampling/createMessage",params:t},q1,n)}elicitInputStream(t,n){let r=this._server.getClientCapabilities(),o=t.mode??"form";switch(o){case"url":{if(!r?.elicitation?.url)throw new Error("Client does not support url elicitation.");break}case"form":{if(!r?.elicitation?.form)throw new Error("Client does not support form elicitation.");break}}let i=o==="form"&&t.mode===void 0?{...t,mode:"form"}:t;return this.requestStream({method:"elicitation/create",params:i},Rx,n)}async getTask(t,n){return this._server.getTask({taskId:t},n)}async getTaskResult(t,n,r){return this._server.getTaskResult({taskId:t},n,r)}async listTasks(t,n){return this._server.listTasks(t?{cursor:t}:void 0,n)}async cancelTask(t,n){return this._server.cancelTask({taskId:t},n)}}});function zQe(e,t,n){if(!e)throw new Error(`${n} does not support task creation (required for ${t})`);switch(t){case"tools/call":if(!e.tools?.call)throw new Error(`${n} does not support task creation for tools/call (required for ${t})`);break;default:break}}function FQe(e,t,n){if(!e)throw new Error(`${n} does not support task creation (required for ${t})`);switch(t){case"sampling/createMessage":if(!e.sampling?.createMessage)throw new Error(`${n} does not support task creation for sampling/createMessage (required for ${t})`);break;case"elicitation/create":if(!e.elicitation?.create)throw new Error(`${n} does not support task creation for elicitation/create (required for ${t})`);break;default:break}}var UQe=B(()=>{});var lj,LQe=B(()=>{TBe();$x();NQe();M1();PQe();UQe();lj=class extends JU{constructor(t,n){super(n),this._serverInfo=t,this._loggingLevels=new Map,this.LOG_LEVEL_SEVERITY=new Map(G1.options.map((r,o)=>[r,o])),this.isMessageIgnored=(r,o)=>{let i=this._loggingLevels.get(o);return i?this.LOG_LEVEL_SEVERITY.get(r)<this.LOG_LEVEL_SEVERITY.get(i):!1},this._capabilities=n?.capabilities??{},this._instructions=n?.instructions,this._jsonSchemaValidator=n?.jsonSchemaValidator??new cj,this.setRequestHandler(see,r=>this._oninitialize(r)),this.setNotificationHandler(aee,()=>this.oninitialized?.()),this._capabilities.logging&&this.setRequestHandler(mee,async(r,o)=>{let i=o.sessionId||o.requestInfo?.headers["mcp-session-id"]||void 0,{level:s}=r.params,c=G1.safeParse(s);return c.success&&this._loggingLevels.set(i,c.data),{}})}get experimental(){return this._experimental||(this._experimental={tasks:new uj(this)}),this._experimental}registerCapabilities(t){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=DBe(this._capabilities,t)}setRequestHandler(t,n){let o=_y(t)?.method;if(!o)throw new Error("Schema is missing a method literal");let i;if(xd(o)){let c=o;i=c._zod?.def?.value??c.value}else{let c=o;i=c._def?.value??c.value}if(typeof i!="string")throw new Error("Schema method literal must be a string");if(i==="tools/call"){let c=async(l,p)=>{let h=Iy(Bx,l);if(!h.success){let I=h.error instanceof Error?h.error.message:String(h.error);throw new vt(Dt.InvalidParams,`Invalid tools/call request: ${I}`)}let{params:g}=h.data,v=await Promise.resolve(n(l,p));if(g.task){let I=Iy(Dx,v);if(!I.success){let x=I.error instanceof Error?I.error.message:String(I.error);throw new vt(Dt.InvalidParams,`Invalid task creation result: ${x}`)}return I.data}let E=Iy(zU,v);if(!E.success){let I=E.error instanceof Error?E.error.message:String(E.error);throw new vt(Dt.InvalidParams,`Invalid tools/call result: ${I}`)}return E.data};return super.setRequestHandler(t,c)}return super.setRequestHandler(t,n)}assertCapabilityForMethod(t){switch(t){case"sampling/createMessage":if(!this._clientCapabilities?.sampling)throw new Error(`Client does not support sampling (required for ${t})`);break;case"elicitation/create":if(!this._clientCapabilities?.elicitation)throw new Error(`Client does not support elicitation (required for ${t})`);break;case"roots/list":if(!this._clientCapabilities?.roots)throw new Error(`Client does not support listing roots (required for ${t})`);break;case"ping":break}}assertNotificationCapability(t){switch(t){case"notifications/message":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${t})`);break;case"notifications/resources/updated":case"notifications/resources/list_changed":if(!this._capabilities.resources)throw new Error(`Server does not support notifying about resources (required for ${t})`);break;case"notifications/tools/list_changed":if(!this._capabilities.tools)throw new Error(`Server does not support notifying of tool list changes (required for ${t})`);break;case"notifications/prompts/list_changed":if(!this._capabilities.prompts)throw new Error(`Server does not support notifying of prompt list changes (required for ${t})`);break;case"notifications/elicitation/complete":if(!this._clientCapabilities?.elicitation?.url)throw new Error(`Client does not support URL elicitation (required for ${t})`);break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(t){if(this._capabilities)switch(t){case"completion/complete":if(!this._capabilities.completions)throw new Error(`Server does not support completions (required for ${t})`);break;case"logging/setLevel":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${t})`);break;case"prompts/get":case"prompts/list":if(!this._capabilities.prompts)throw new Error(`Server does not support prompts (required for ${t})`);break;case"resources/list":case"resources/templates/list":case"resources/read":if(!this._capabilities.resources)throw new Error(`Server does not support resources (required for ${t})`);break;case"tools/call":case"tools/list":if(!this._capabilities.tools)throw new Error(`Server does not support tools (required for ${t})`);break;case"tasks/get":case"tasks/list":case"tasks/result":case"tasks/cancel":if(!this._capabilities.tasks)throw new Error(`Server does not support tasks capability (required for ${t})`);break;case"ping":case"initialize":break}}assertTaskCapability(t){FQe(this._clientCapabilities?.tasks?.requests,t,"Client")}assertTaskHandlerCapability(t){this._capabilities&&zQe(this._capabilities.tasks?.requests,t,"Server")}async _oninitialize(t){let n=t.params.protocolVersion;return this._clientCapabilities=t.params.capabilities,this._clientVersion=t.params.clientInfo,{protocolVersion:DTe.includes(n)?n:tee,capabilities:this.getCapabilities(),serverInfo:this._serverInfo,...this._instructions&&{instructions:this._instructions}}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},bU)}async createMessage(t,n){if((t.tools||t.toolChoice)&&!this._clientCapabilities?.sampling?.tools)throw new Error("Client does not support sampling tools capability.");if(t.messages.length>0){let r=t.messages[t.messages.length-1],o=Array.isArray(r.content)?r.content:[r.content],i=o.some(p=>p.type==="tool_result"),s=t.messages.length>1?t.messages[t.messages.length-2]:void 0,c=s?Array.isArray(s.content)?s.content:[s.content]:[],l=c.some(p=>p.type==="tool_use");if(i){if(o.some(p=>p.type!=="tool_result"))throw new Error("The last message must contain only tool_result content if any is present");if(!l)throw new Error("tool_result blocks are not matching any tool_use from the previous message")}if(l){let p=new Set(c.filter(g=>g.type==="tool_use").map(g=>g.id)),h=new Set(o.filter(g=>g.type==="tool_result").map(g=>g.toolUseId));if(p.size!==h.size||![...p].every(g=>h.has(g)))throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}return t.tools?this.request({method:"sampling/createMessage",params:t},hee,n):this.request({method:"sampling/createMessage",params:t},q1,n)}async elicitInput(t,n){switch(t.mode??"form"){case"url":{if(!this._clientCapabilities?.elicitation?.url)throw new Error("Client does not support url elicitation.");let o=t;return this.request({method:"elicitation/create",params:o},Rx,n)}case"form":{if(!this._clientCapabilities?.elicitation?.form)throw new Error("Client does not support form elicitation.");let o=t.mode==="form"?t:{...t,mode:"form"},i=await this.request({method:"elicitation/create",params:o},Rx,n);if(i.action==="accept"&&i.content&&o.requestedSchema)try{let c=this._jsonSchemaValidator.getValidator(o.requestedSchema)(i.content);if(!c.valid)throw new vt(Dt.InvalidParams,`Elicitation response content does not match requested schema: ${c.errorMessage}`)}catch(s){throw s instanceof vt?s:new vt(Dt.InternalError,`Error validating elicitation response: ${s instanceof Error?s.message:String(s)}`)}return i}}}createElicitationCompletionNotifier(t,n){if(!this._clientCapabilities?.elicitation?.url)throw new Error("Client does not support URL elicitation (required for notifications/elicitation/complete)");return()=>this.notification({method:"notifications/elicitation/complete",params:{elicitationId:t}},n)}async listRoots(t,n){return this.request({method:"roots/list",params:t},gee,n)}async sendLoggingMessage(t,n){if(this._capabilities.logging&&!this.isMessageIgnored(t.level,n))return this.notification({method:"notifications/message",params:t})}async sendResourceUpdated(t){return this.notification({method:"notifications/resources/updated",params:t})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}}});function Ioe(e){return!!e&&typeof e=="object"&&HQe in e}function GQe(e){return e[HQe]?.complete}var HQe,jQe,qQe=B(()=>{HQe=Symbol.for("mcp.completable");(function(e){e.Completable="McpCompletable"})(jQe||(jQe={}))});var ZQe=B(()=>{});function ngt(e){let t=[];if(e.length===0)return{isValid:!1,warnings:["Tool name cannot be empty"]};if(e.length>128)return{isValid:!1,warnings:[`Tool name exceeds maximum length of 128 characters (current: ${e.length})`]};if(e.includes(" ")&&t.push("Tool name contains spaces, which may cause parsing issues"),e.includes(",")&&t.push("Tool name contains commas, which may cause parsing issues"),(e.startsWith("-")||e.endsWith("-"))&&t.push("Tool name starts or ends with a dash, which may cause parsing issues in some contexts"),(e.startsWith(".")||e.endsWith("."))&&t.push("Tool name starts or ends with a dot, which may cause parsing issues in some contexts"),!tgt.test(e)){let n=e.split("").filter(r=>!/[A-Za-z0-9._-]/.test(r)).filter((r,o,i)=>i.indexOf(r)===o);return t.push(`Tool name contains invalid characters: ${n.map(r=>`"${r}"`).join(", ")}`,"Allowed characters are: A-Z, a-z, 0-9, underscore (_), dash (-), and dot (.)"),{isValid:!1,warnings:t}}return{isValid:!0,warnings:t}}function rgt(e,t){if(t.length>0){console.warn(`Tool name validation warning for "${e}":`);for(let n of t)console.warn(` - ${n}`);console.warn("Tool registration will proceed, but this may cause compatibility issues."),console.warn("Consider updating the tool name to conform to the MCP tool naming standard."),console.warn("See SEP: Specify Format for Tool Names (https://github.com/modelcontextprotocol/modelcontextprotocol/issues/986) for more details.")}}function _oe(e){let t=ngt(e);return rgt(e,t.warnings),t.isValid}var tgt,KQe=B(()=>{tgt=/^[A-Za-z0-9._-]{1,128}$/});var dj,YQe=B(()=>{dj=class{constructor(t){this._mcpServer=t}registerToolTask(t,n,r){let o={taskSupport:"required",...n.execution};if(o.taskSupport==="forbidden")throw new Error(`Cannot register task-based tool '${t}' with taskSupport 'forbidden'. Use registerTool() instead.`);return this._mcpServer._createRegisteredTool(t,n.title,n.description,n.inputSchema,n.outputSchema,n.annotations,o,n._meta,r)}}});var xoe=B(()=>{ZF();ZF()});function WQe(e){return e!==null&&typeof e=="object"&&"parse"in e&&typeof e.parse=="function"&&"safeParse"in e&&typeof e.safeParse=="function"}function XQe(e){return"_def"in e||"_zod"in e||WQe(e)}function woe(e){return typeof e!="object"||e===null||XQe(e)?!1:Object.keys(e).length===0?!0:Object.values(e).some(WQe)}function VQe(e){if(e){if(woe(e))return oE(e);if(!XQe(e))throw new Error("inputSchema must be a Zod schema or raw shape, received an unrecognized object");return e}}function igt(e){let t=_y(e);return t?Object.entries(t).map(([n,r])=>{let o=eTe(r),i=tTe(r);return{name:n,description:o,required:!i}}):[]}function Hy(e){let n=_y(e)?.method;if(!n)throw new Error("Schema is missing a method literal");let r=AU(n);if(typeof r=="string")return r;throw new Error("Schema method literal must be a string")}function JQe(e){return{completion:{values:e.slice(0,100),total:e.length,hasMore:e.length>100}}}var fj,ogt,JR,eOe=B(()=>{LQe();M1();Xee();$x();qQe();ZQe();KQe();YQe();xoe();fj=class{constructor(t,n){this._registeredResources={},this._registeredResourceTemplates={},this._registeredTools={},this._registeredPrompts={},this._toolHandlersInitialized=!1,this._completionHandlerInitialized=!1,this._resourceHandlersInitialized=!1,this._promptHandlersInitialized=!1,this.server=new lj(t,n)}get experimental(){return this._experimental||(this._experimental={tasks:new dj(this)}),this._experimental}async connect(t){return await this.server.connect(t)}async close(){await this.server.close()}setToolRequestHandlers(){this._toolHandlersInitialized||(this.server.assertCanSetRequestHandler(Hy(PU)),this.server.assertCanSetRequestHandler(Hy(Bx)),this.server.registerCapabilities({tools:{listChanged:!0}}),this.server.setRequestHandler(PU,()=>({tools:Object.entries(this._registeredTools).filter(([,t])=>t.enabled).map(([t,n])=>{let r={name:t,title:n.title,description:n.description,inputSchema:(()=>{let o=wx(n.inputSchema);return o?Vee(o,{strictUnions:!0,pipeStrategy:"input"}):ogt})(),annotations:n.annotations,execution:n.execution,_meta:n._meta};if(n.outputSchema){let o=wx(n.outputSchema);o&&(r.outputSchema=Vee(o,{strictUnions:!0,pipeStrategy:"output"}))}return r})})),this.server.setRequestHandler(Bx,async(t,n)=>{try{let r=this._registeredTools[t.params.name];if(!r)throw new vt(Dt.InvalidParams,`Tool ${t.params.name} not found`);if(!r.enabled)throw new vt(Dt.InvalidParams,`Tool ${t.params.name} disabled`);let o=!!t.params.task,i=r.execution?.taskSupport,s="createTask"in r.handler;if((i==="required"||i==="optional")&&!s)throw new vt(Dt.InternalError,`Tool ${t.params.name} has taskSupport '${i}' but was not registered with registerToolTask`);if(i==="required"&&!o)throw new vt(Dt.MethodNotFound,`Tool ${t.params.name} requires task augmentation (taskSupport: 'required')`);if(i==="optional"&&!o&&s)return await this.handleAutomaticTaskPolling(r,t,n);let c=await this.validateToolInput(r,t.params.arguments,t.params.name),l=await this.executeToolHandler(r,c,n);return o||await this.validateToolOutput(r,l,t.params.name),l}catch(r){if(r instanceof vt&&r.code===Dt.UrlElicitationRequired)throw r;return this.createToolError(r instanceof Error?r.message:String(r))}}),this._toolHandlersInitialized=!0)}createToolError(t){return{content:[{type:"text",text:t}],isError:!0}}async validateToolInput(t,n,r){if(!t.inputSchema)return;let i=wx(t.inputSchema)??t.inputSchema,s=await hU(i,n);if(!s.success){let c="error"in s?s.error:"Unknown error",l=gU(c);throw new vt(Dt.InvalidParams,`Input validation error: Invalid arguments for tool ${r}: ${l}`)}return s.data}async validateToolOutput(t,n,r){if(!t.outputSchema||!("content"in n)||n.isError)return;if(!n.structuredContent)throw new vt(Dt.InvalidParams,`Output validation error: Tool ${r} has an output schema but no structured content was provided`);let o=wx(t.outputSchema),i=await hU(o,n.structuredContent);if(!i.success){let s="error"in i?i.error:"Unknown error",c=gU(s);throw new vt(Dt.InvalidParams,`Output validation error: Invalid structured content for tool ${r}: ${c}`)}}async executeToolHandler(t,n,r){let o=t.handler;if("createTask"in o){if(!r.taskStore)throw new Error("No task store provided.");let s={...r,taskStore:r.taskStore};if(t.inputSchema){let c=o;return await Promise.resolve(c.createTask(n,s))}else{let c=o;return await Promise.resolve(c.createTask(s))}}if(t.inputSchema){let s=o;return await Promise.resolve(s(n,r))}else{let s=o;return await Promise.resolve(s(r))}}async handleAutomaticTaskPolling(t,n,r){if(!r.taskStore)throw new Error("No task store provided for task-capable tool.");let o=await this.validateToolInput(t,n.params.arguments,n.params.name),i=t.handler,s={...r,taskStore:r.taskStore},c=o?await Promise.resolve(i.createTask(o,s)):await Promise.resolve(i.createTask(s)),l=c.task.taskId,p=c.task,h=p.pollInterval??5e3;for(;p.status!=="completed"&&p.status!=="failed"&&p.status!=="cancelled";){await new Promise(v=>setTimeout(v,h));let g=await r.taskStore.getTask(l);if(!g)throw new vt(Dt.InternalError,`Task ${l} not found during polling`);p=g}return await r.taskStore.getTaskResult(l)}setCompletionRequestHandler(){this._completionHandlerInitialized||(this.server.assertCanSetRequestHandler(Hy(FU)),this.server.registerCapabilities({completions:{}}),this.server.setRequestHandler(FU,async t=>{switch(t.params.ref.type){case"ref/prompt":return GTe(t),this.handlePromptCompletion(t,t.params.ref);case"ref/resource":return qTe(t),this.handleResourceCompletion(t,t.params.ref);default:throw new vt(Dt.InvalidParams,`Invalid completion reference: ${t.params.ref}`)}}),this._completionHandlerInitialized=!0)}async handlePromptCompletion(t,n){let r=this._registeredPrompts[n.name];if(!r)throw new vt(Dt.InvalidParams,`Prompt ${n.name} not found`);if(!r.enabled)throw new vt(Dt.InvalidParams,`Prompt ${n.name} disabled`);if(!r.argsSchema)return JR;let i=_y(r.argsSchema)?.[t.params.argument.name];if(!Ioe(i))return JR;let s=GQe(i);if(!s)return JR;let c=await s(t.params.argument.value,t.params.context);return JQe(c)}async handleResourceCompletion(t,n){let r=Object.values(this._registeredResourceTemplates).find(s=>s.resourceTemplate.uriTemplate.toString()===n.uri);if(!r){if(this._registeredResources[n.uri])return JR;throw new vt(Dt.InvalidParams,`Resource template ${t.params.ref.uri} not found`)}let o=r.resourceTemplate.completeCallback(t.params.argument.name);if(!o)return JR;let i=await o(t.params.argument.value,t.params.context);return JQe(i)}setResourceRequestHandlers(){this._resourceHandlersInitialized||(this.server.assertCanSetRequestHandler(Hy($U)),this.server.assertCanSetRequestHandler(Hy(MU)),this.server.assertCanSetRequestHandler(Hy(QU)),this.server.registerCapabilities({resources:{listChanged:!0}}),this.server.setRequestHandler($U,async(t,n)=>{let r=Object.entries(this._registeredResources).filter(([i,s])=>s.enabled).map(([i,s])=>({uri:i,name:s.name,...s.metadata})),o=[];for(let i of Object.values(this._registeredResourceTemplates)){if(!i.resourceTemplate.listCallback)continue;let s=await i.resourceTemplate.listCallback(n);for(let c of s.resources)o.push({...i.metadata,...c})}return{resources:[...r,...o]}}),this.server.setRequestHandler(MU,async()=>({resourceTemplates:Object.entries(this._registeredResourceTemplates).map(([n,r])=>({name:n,uriTemplate:r.resourceTemplate.uriTemplate.toString(),...r.metadata}))})),this.server.setRequestHandler(QU,async(t,n)=>{let r=new URL(t.params.uri),o=this._registeredResources[r.toString()];if(o){if(!o.enabled)throw new vt(Dt.InvalidParams,`Resource ${r} disabled`);return o.readCallback(r,n)}for(let i of Object.values(this._registeredResourceTemplates)){let s=i.resourceTemplate.uriTemplate.match(r.toString());if(s)return i.readCallback(r,s,n)}throw new vt(Dt.InvalidParams,`Resource ${r} not found`)}),this._resourceHandlersInitialized=!0)}setPromptRequestHandlers(){this._promptHandlersInitialized||(this.server.assertCanSetRequestHandler(Hy(OU)),this.server.assertCanSetRequestHandler(Hy(NU)),this.server.registerCapabilities({prompts:{listChanged:!0}}),this.server.setRequestHandler(OU,()=>({prompts:Object.entries(this._registeredPrompts).filter(([,t])=>t.enabled).map(([t,n])=>({name:t,title:n.title,description:n.description,arguments:n.argsSchema?igt(n.argsSchema):void 0}))})),this.server.setRequestHandler(NU,async(t,n)=>{let r=this._registeredPrompts[t.params.name];if(!r)throw new vt(Dt.InvalidParams,`Prompt ${t.params.name} not found`);if(!r.enabled)throw new vt(Dt.InvalidParams,`Prompt ${t.params.name} disabled`);if(r.argsSchema){let o=wx(r.argsSchema),i=await hU(o,t.params.arguments);if(!i.success){let l="error"in i?i.error:"Unknown error",p=gU(l);throw new vt(Dt.InvalidParams,`Invalid arguments for prompt ${t.params.name}: ${p}`)}let s=i.data,c=r.callback;return await Promise.resolve(c(s,n))}else{let o=r.callback;return await Promise.resolve(o(n))}}),this._promptHandlersInitialized=!0)}resource(t,n,...r){let o;typeof r[0]=="object"&&(o=r.shift());let i=r[0];if(typeof n=="string"){if(this._registeredResources[n])throw new Error(`Resource ${n} is already registered`);let s=this._createRegisteredResource(t,void 0,n,o,i);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),s}else{if(this._registeredResourceTemplates[t])throw new Error(`Resource template ${t} is already registered`);let s=this._createRegisteredResourceTemplate(t,void 0,n,o,i);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),s}}registerResource(t,n,r,o){if(typeof n=="string"){if(this._registeredResources[n])throw new Error(`Resource ${n} is already registered`);let i=this._createRegisteredResource(t,r.title,n,r,o);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),i}else{if(this._registeredResourceTemplates[t])throw new Error(`Resource template ${t} is already registered`);let i=this._createRegisteredResourceTemplate(t,r.title,n,r,o);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),i}}_createRegisteredResource(t,n,r,o,i){let s={name:t,title:n,metadata:o,readCallback:i,enabled:!0,disable:()=>s.update({enabled:!1}),enable:()=>s.update({enabled:!0}),remove:()=>s.update({uri:null}),update:c=>{typeof c.uri<"u"&&c.uri!==r&&(delete this._registeredResources[r],c.uri&&(this._registeredResources[c.uri]=s)),typeof c.name<"u"&&(s.name=c.name),typeof c.title<"u"&&(s.title=c.title),typeof c.metadata<"u"&&(s.metadata=c.metadata),typeof c.callback<"u"&&(s.readCallback=c.callback),typeof c.enabled<"u"&&(s.enabled=c.enabled),this.sendResourceListChanged()}};return this._registeredResources[r]=s,s}_createRegisteredResourceTemplate(t,n,r,o,i){let s={resourceTemplate:r,title:n,metadata:o,readCallback:i,enabled:!0,disable:()=>s.update({enabled:!1}),enable:()=>s.update({enabled:!0}),remove:()=>s.update({name:null}),update:p=>{typeof p.name<"u"&&p.name!==t&&(delete this._registeredResourceTemplates[t],p.name&&(this._registeredResourceTemplates[p.name]=s)),typeof p.title<"u"&&(s.title=p.title),typeof p.template<"u"&&(s.resourceTemplate=p.template),typeof p.metadata<"u"&&(s.metadata=p.metadata),typeof p.callback<"u"&&(s.readCallback=p.callback),typeof p.enabled<"u"&&(s.enabled=p.enabled),this.sendResourceListChanged()}};this._registeredResourceTemplates[t]=s;let c=r.uriTemplate.variableNames;return Array.isArray(c)&&c.some(p=>!!r.completeCallback(p))&&this.setCompletionRequestHandler(),s}_createRegisteredPrompt(t,n,r,o,i){let s={title:n,description:r,argsSchema:o===void 0?void 0:oE(o),callback:i,enabled:!0,disable:()=>s.update({enabled:!1}),enable:()=>s.update({enabled:!0}),remove:()=>s.update({name:null}),update:c=>{typeof c.name<"u"&&c.name!==t&&(delete this._registeredPrompts[t],c.name&&(this._registeredPrompts[c.name]=s)),typeof c.title<"u"&&(s.title=c.title),typeof c.description<"u"&&(s.description=c.description),typeof c.argsSchema<"u"&&(s.argsSchema=oE(c.argsSchema)),typeof c.callback<"u"&&(s.callback=c.callback),typeof c.enabled<"u"&&(s.enabled=c.enabled),this.sendPromptListChanged()}};return this._registeredPrompts[t]=s,o&&Object.values(o).some(l=>{let p=l instanceof _u?l._def?.innerType:l;return Ioe(p)})&&this.setCompletionRequestHandler(),s}_createRegisteredTool(t,n,r,o,i,s,c,l,p){_oe(t);let h={title:n,description:r,inputSchema:VQe(o),outputSchema:VQe(i),annotations:s,execution:c,_meta:l,handler:p,enabled:!0,disable:()=>h.update({enabled:!1}),enable:()=>h.update({enabled:!0}),remove:()=>h.update({name:null}),update:g=>{typeof g.name<"u"&&g.name!==t&&(typeof g.name=="string"&&_oe(g.name),delete this._registeredTools[t],g.name&&(this._registeredTools[g.name]=h)),typeof g.title<"u"&&(h.title=g.title),typeof g.description<"u"&&(h.description=g.description),typeof g.paramsSchema<"u"&&(h.inputSchema=oE(g.paramsSchema)),typeof g.outputSchema<"u"&&(h.outputSchema=oE(g.outputSchema)),typeof g.callback<"u"&&(h.handler=g.callback),typeof g.annotations<"u"&&(h.annotations=g.annotations),typeof g._meta<"u"&&(h._meta=g._meta),typeof g.enabled<"u"&&(h.enabled=g.enabled),this.sendToolListChanged()}};return this._registeredTools[t]=h,this.setToolRequestHandlers(),this.sendToolListChanged(),h}tool(t,...n){if(this._registeredTools[t])throw new Error(`Tool ${t} is already registered`);let r,o,i,s;if(typeof n[0]=="string"&&(r=n.shift()),n.length>1){let l=n[0];if(woe(l))o=n.shift(),n.length>1&&typeof n[0]=="object"&&n[0]!==null&&!woe(n[0])&&(s=n.shift());else if(typeof l=="object"&&l!==null){if(Object.values(l).some(p=>typeof p=="object"&&p!==null))throw new Error(`Tool ${t} expected a Zod schema or ToolAnnotations, but received an unrecognized object`);s=n.shift()}}let c=n[0];return this._createRegisteredTool(t,void 0,r,o,i,s,{taskSupport:"forbidden"},void 0,c)}registerTool(t,n,r){if(this._registeredTools[t])throw new Error(`Tool ${t} is already registered`);let{title:o,description:i,inputSchema:s,outputSchema:c,annotations:l,_meta:p}=n;return this._createRegisteredTool(t,o,i,s,c,l,{taskSupport:"forbidden"},p,r)}prompt(t,...n){if(this._registeredPrompts[t])throw new Error(`Prompt ${t} is already registered`);let r;typeof n[0]=="string"&&(r=n.shift());let o;n.length>1&&(o=n.shift());let i=n[0],s=this._createRegisteredPrompt(t,void 0,r,o,i);return this.setPromptRequestHandlers(),this.sendPromptListChanged(),s}registerPrompt(t,n,r){if(this._registeredPrompts[t])throw new Error(`Prompt ${t} is already registered`);let{title:o,description:i,argsSchema:s}=n,c=this._createRegisteredPrompt(t,o,i,s,r);return this.setPromptRequestHandlers(),this.sendPromptListChanged(),c}isConnected(){return this.server.transport!==void 0}async sendLoggingMessage(t,n){return this.server.sendLoggingMessage(t,n)}sendResourceListChanged(){this.isConnected()&&this.server.sendResourceListChanged()}sendToolListChanged(){this.isConnected()&&this.server.sendToolListChanged()}sendPromptListChanged(){this.isConnected()&&this.server.sendPromptListChanged()}},ogt={type:"object",properties:{}};JR={completion:{values:[],hasMore:!1}}});function sgt(e){return NTe.parse(JSON.parse(e))}function tOe(e){return JSON.stringify(e)+`
|
|
1279
1279
|
`}var pj,nOe=B(()=>{$x();pj=class{append(t){this._buffer=this._buffer?Buffer.concat([this._buffer,t]):t}readMessage(){if(!this._buffer)return null;let t=this._buffer.indexOf(`
|
|
1280
|
-
`);if(t===-1)return null;let n=this._buffer.toString("utf8",0,t).replace(/\r$/,"");return this._buffer=this._buffer.subarray(t+1),sgt(n)}clear(){this._buffer=void 0}}});import rOe from"node:process";var mj,oOe=B(()=>{nOe();mj=class{constructor(t=rOe.stdin,n=rOe.stdout){this._stdin=t,this._stdout=n,this._readBuffer=new pj,this._started=!1,this._ondata=r=>{this._readBuffer.append(r),this.processReadBuffer()},this._onerror=r=>{this.onerror?.(r)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(;;)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t)}catch(t){this.onerror?.(t)}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.()}send(t){return new Promise(n=>{let r=tOe(t);this._stdout.write(r)?n():this._stdout.once("drain",n)})}}});var cOe={};hn(cOe,{createMcpFactsServer:()=>aOe,mcpAction:()=>cgt});function sOe(e){return e==="codex"?new da:e==="opencode"?new If:new dl}function xE(e){return{content:[{type:"text",text:JSON.stringify(e,null,2)}],structuredContent:{data:e??null}}}async function iOe(e,t){let n=sOe(t);try{let r=n.findActiveSession(e);if(!r)return null;let o=n.createReader(r).readAll(),i=n.computeContextSize?l=>n.computeContextSize({...l,model:"",timestamp:new Date}):void 0,s=new Ec({providerId:t,computeContextSize:i});for(let l of o)s.processEvent(l);let c=n.readSessionContextSnapshot?.(r)??HN(o,{providerId:t,sessionId:n.getSessionId(r),sessionPath:r,contextWindowForModel:n.getContextWindowLimit?.bind(n),computeContextSize:i});return{sessionPath:r,metrics:s.getMetrics(),snapshot:c}}finally{n.dispose()}}function agt(e,t){return Qf({providerId:t==="opencode"?"zai":t,workspacePath:e,...t==="codex"?{preferFresh:!1}:{}})}function aOe(e){let t=e.providerId??L0(),n=e.cwd,r=xr(n),o=new fj({name:"sidekick-agent-hub",version:"0.28.
|
|
1280
|
+
`);if(t===-1)return null;let n=this._buffer.toString("utf8",0,t).replace(/\r$/,"");return this._buffer=this._buffer.subarray(t+1),sgt(n)}clear(){this._buffer=void 0}}});import rOe from"node:process";var mj,oOe=B(()=>{nOe();mj=class{constructor(t=rOe.stdin,n=rOe.stdout){this._stdin=t,this._stdout=n,this._readBuffer=new pj,this._started=!1,this._ondata=r=>{this._readBuffer.append(r),this.processReadBuffer()},this._onerror=r=>{this.onerror?.(r)}}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){for(;;)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t)}catch(t){this.onerror?.(t)}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.()}send(t){return new Promise(n=>{let r=tOe(t);this._stdout.write(r)?n():this._stdout.once("drain",n)})}}});var cOe={};hn(cOe,{createMcpFactsServer:()=>aOe,mcpAction:()=>cgt});function sOe(e){return e==="codex"?new da:e==="opencode"?new If:new dl}function xE(e){return{content:[{type:"text",text:JSON.stringify(e,null,2)}],structuredContent:{data:e??null}}}async function iOe(e,t){let n=sOe(t);try{let r=n.findActiveSession(e);if(!r)return null;let o=n.createReader(r).readAll(),i=n.computeContextSize?l=>n.computeContextSize({...l,model:"",timestamp:new Date}):void 0,s=new Ec({providerId:t,computeContextSize:i});for(let l of o)s.processEvent(l);let c=n.readSessionContextSnapshot?.(r)??HN(o,{providerId:t,sessionId:n.getSessionId(r),sessionPath:r,contextWindowForModel:n.getContextWindowLimit?.bind(n),computeContextSize:i});return{sessionPath:r,metrics:s.getMetrics(),snapshot:c}}finally{n.dispose()}}function agt(e,t){return Qf({providerId:t==="opencode"?"zai":t,workspacePath:e,...t==="codex"?{preferFresh:!1}:{}})}function aOe(e){let t=e.providerId??L0(),n=e.cwd,r=xr(n),o=new fj({name:"sidekick-agent-hub",version:"0.28.1"},{instructions:"Read-only facts about the current coding-agent session, quota, and Sidekick project stores."}),i={title:"",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0};return o.registerTool("get_quota_status",{description:"Get current quota utilization and reset windows using the same resolver as sidekick quota.",inputSchema:qf.object({}),annotations:{...i,title:"Get quota status"}},async()=>xE(await agt(n,t))),o.registerTool("get_burn_rate",{description:"Get current token burn rate for the active observed session.",inputSchema:qf.object({}),annotations:{...i,title:"Get burn rate"}},async()=>{let s=await iOe(n,t);return xE(s?s.metrics.burnRate:null)}),o.registerTool("get_context_pressure",{description:"Get provider-neutral context pressure and compaction facts for the active session.",inputSchema:qf.object({}),annotations:{...i,title:"Get context pressure"}},async()=>{let s=await iOe(n,t);return xE(s?.snapshot??null)}),o.registerTool("get_tasks",{description:"List persisted tasks for the current project.",inputSchema:qf.object({}),annotations:{...i,title:"Get tasks"}},async()=>xE(await hh(r,{status:"all"}))),o.registerTool("get_decisions",{description:"List persisted architectural decisions for the current project.",inputSchema:qf.object({}),annotations:{...i,title:"Get decisions"}},async()=>xE(await gh(r))),o.registerTool("get_notes",{description:"List persisted knowledge notes for the current project.",inputSchema:qf.object({}),annotations:{...i,title:"Get notes"}},async()=>xE(await Ah(r))),o.registerTool("get_project_context",{description:"Compose tasks, decisions, notes, handoff, and stats for the current project.",inputSchema:qf.object({fidelity:qf.enum(["full","compact","brief"]).default("compact")}),annotations:{...i,title:"Get project context"}},async({fidelity:s})=>{let c=sOe(t);try{return xE(await j0(r,s,c))}finally{c.dispose()}}),o}async function cgt(e,t){let n=t.parent.opts(),r=n.provider&&n.provider!=="auto"?n.provider:void 0;await aOe({cwd:n.project||process.cwd(),providerId:r}).connect(new mj)}var uOe=B(()=>{"use strict";eOe();oOe();xoe();Pt()});var pOe={};hn(pOe,{formatDailyCsv:()=>dOe,formatFailingToolsBlock:()=>fOe,statsAction:()=>lgt});function ip(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":e.toLocaleString()}function ugt(e,t,n=[]){let r=e.allTime;process.stdout.write(F.bold(`All-Time Stats
|
|
1281
1281
|
`)),process.stdout.write(F.dim("\u2500".repeat(50)+`
|
|
1282
1282
|
`));let o=Ei(r.tokens).total;process.stdout.write(` ${F.dim("Sessions:")} ${F.bold(ip(r.sessionCount))}
|
|
1283
1283
|
`),process.stdout.write(` ${F.dim("Messages:")} ${F.bold(ip(r.messageCount))}
|
|
@@ -1412,7 +1412,7 @@ ${z.join(`
|
|
|
1412
1412
|
`))}catch(i){let s=i instanceof Error?i.message:String(i);process.stderr.write(`Error: ${s}
|
|
1413
1413
|
`),process.exit(1)}}async function bAt(e,t){let n=t.parent.parent.opts(),r=t.opts(),o=n.project||process.cwd(),i=r.urlTemplate||process.env.SIDEKICK_HANDOFF_URL_TEMPLATE||"",s=Wi(n);try{let c=s.findActiveSession(o),l=r.session||(c?s.getSessionId(c):"unknown"),p=oq(i,{sessionId:l,provider:s.id,projectPath:o}),g=r.open!==!1&&!n.json?_j(p):!1;n.json?process.stdout.write(`${JSON.stringify({url:p,opened:g})}
|
|
1414
1414
|
`):process.stdout.write(`${g?"Opened":"Handoff URL"}: ${p}
|
|
1415
|
-
`)}finally{s.dispose()}}var zoe=B(()=>{"use strict";_i();Pt();Cl();Ooe()});function t$(e,t="auto"){return e.provider&&e.provider!=="auto"?e.provider:t!=="auto"?t:L0()}function Wi(e){switch(t$(e)){case"opencode":return new If;case"codex":return new da;default:return new dl}}function xj(e,t){return new Gr(e).description(t).option("--since <time>","Start of the window: ISO date, YYYY-MM-DD, or a relative window such as 30d").option("--until <time>","End of the window (default: now)").option("--breakdown","Add per-model sub-rows under every row").option("--by-project","Group rows by project as well as provider").option("--utc","Bucket by UTC calendar days instead of local days").option("--csv","Print rows as CSV").option("--no-cache","Re-read every session instead of using the usage cache").addHelpText("after",Fse)}var n$,cr,IAt,_At,xAt,wAt,kAt,DAt,Foe,TAt,BAt,TNe,BNe,RAt,$At,MAt,QAt,OAt,NAt,RNe,PAt,zAt,FAt,UAt,LAt,$Ne,Cl=B(()=>{XM();Gse();Kse();bye();kye();Pt();Pt();Tye();$Ie();n$=Zse(process.argv.slice(2)),cr=new Gr;cr.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.28.
|
|
1415
|
+
`)}finally{s.dispose()}}var zoe=B(()=>{"use strict";_i();Pt();Cl();Ooe()});function t$(e,t="auto"){return e.provider&&e.provider!=="auto"?e.provider:t!=="auto"?t:L0()}function Wi(e){switch(t$(e)){case"opencode":return new If;case"codex":return new da;default:return new dl}}function xj(e,t){return new Gr(e).description(t).option("--since <time>","Start of the window: ISO date, YYYY-MM-DD, or a relative window such as 30d").option("--until <time>","End of the window (default: now)").option("--breakdown","Add per-model sub-rows under every row").option("--by-project","Group rows by project as well as provider").option("--utc","Bucket by UTC calendar days instead of local days").option("--csv","Print rows as CSV").option("--no-cache","Re-read every session instead of using the usage cache").addHelpText("after",Fse)}var n$,cr,IAt,_At,xAt,wAt,kAt,DAt,Foe,TAt,BAt,TNe,BNe,RAt,$At,MAt,QAt,OAt,NAt,RNe,PAt,zAt,FAt,UAt,LAt,$Ne,Cl=B(()=>{XM();Gse();Kse();bye();kye();Pt();Pt();Tye();$Ie();n$=Zse(process.argv.slice(2)),cr=new Gr;cr.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.28.1").option("--json","Output as JSON").option("--project <path>","Override project path (default: cwd)").option("--no-color","Disable colored output (also honors NO_COLOR)").option("--offline","Price from the cached catalog only; never refresh it over the network (also SIDEKICK_OFFLINE=1)").option("--output-file <path>","Write everything the command prints to stdout into this file").addOption(WK()).addHelpText("after",Nse);cr.hook("preAction",async(e,t)=>{let n=cr.opts().outputFile;if(n){let{installOutputRedirect:o,REDIRECT_UNSUPPORTED_COMMANDS:i}=await Promise.resolve().then(()=>(QIe(),MIe));n$&&i.has(n$)?process.stderr.write(`--output-file is ignored for '${n$}'.
|
|
1416
1416
|
`):o(n)}let r=t.name()==="doctor"&&["accounts","account"].includes(t.parent?.name()??"");return Sye(n$,{accountDoctor:r})});IAt=new Gr("dashboard").description("Full-screen TUI dashboard with live session metrics").option("--session <id>","Follow a specific session (default: most recent)").option("--replay","Replay existing events before streaming new ones").option("--no-mouse","Disable mouse capture so terminal text selection works (toggle with M)").action(async(e,t)=>{let{dashboardAction:n}=await hwe().then(()=>mwe);return n(e,t)});cr.addCommand(IAt);_At=new Gr("dump").description("Dump session data as text timeline, JSON metrics, or markdown report; --prompts dumps prompts by session").option("--list","List available session IDs for the current project").option("--csv","With --list, print the session table as CSV").option("--limit <n>","Maximum sessions listed with --list (default: 50), or dumped with --prompts").option("--session <id>","Target a specific session (default: most recent)").option("--width <cols>","Terminal width for text output (default: auto-detect)").option("--expand","Show all events including noise").option("--format <fmt>","Output format: text, json, markdown (default: text); jsonl too with --prompts").option("--prompts","Dump every human prompt grouped by session (Claude Code and Codex)").option("--all","With --prompts, every session of this project and its worktrees").option("--since <time>","With --prompts, sessions active since an ISO date, YYYY-MM-DD, or 7d/24h (returned whole)").option("--signals","With --prompts, add interrupts, rejected/failed tools, compactions, API errors, rollbacks").option("--replies","With --prompts, add the agent's final reply to each prompt").addHelpText("after",jse).action(async(e,t)=>{let{dumpAction:n}=await Promise.resolve().then(()=>(Pwe(),Nwe));return n(e,t)});cr.addCommand(_At);xAt=new Gr("history").description("Show recent prompts across Codex sessions (prompt history \u2014 for the quota heatmap use `sidekick quota history`)").option("--limit <n>","Maximum prompts to show (default: 20)").option("--path <sessionId>","Print the rollout transcript path for a session ID or prefix").addHelpText("after",Hse).action(async(e,t)=>{let{historyAction:n}=await Promise.resolve().then(()=>(jwe(),Lwe));return n(e,t)});cr.addCommand(xAt);wAt=new Gr("context").description("Output composite project context: tasks, decisions, notes, and handoff").option("--fidelity <level>","Detail level: full, compact, brief (default: full)").action(async(e,t)=>{let{contextAction:n}=await Promise.resolve().then(()=>(Gwe(),Hwe));return n(e,t)});cr.addCommand(wAt);kAt=new Gr("report").description("Generate a self-contained HTML session report and open in browser").option("--session <id>","Target a specific session (default: most recent)").option("--output <path>","Write report to a specific file path (default: temp file)").option("--no-open","Do not auto-open the report in the browser").addOption(xye()).option("--no-thinking","Exclude thinking blocks from the transcript").addHelpText("after",`
|
|
1417
1417
|
With the global --json flag the report path is printed to stdout as {"path": ...}.
|
|
1418
1418
|
`).action(async(e,t)=>{let{reportAction:n}=await Promise.resolve().then(()=>(Vwe(),Ywe));return n(e,t)});cr.addCommand(kAt);DAt=new Gr("search").description("Full-text search across all sessions").argument("<query>","Search query string").option("--limit <n>","Maximum number of results (default: 50)").action(async(e,t,n)=>{n.opts().query=e;let{searchAction:r}=await Promise.resolve().then(()=>(Wwe(),Jwe));return r(t,n)});cr.addCommand(DAt);Foe=new Gr("tasks").description("List persisted tasks for the current project").addOption(wye()).action(async(e,t)=>{let{tasksAction:n}=await Promise.resolve().then(()=>(eke(),Xwe));return n(e,t)});Foe.command("add").description("Add a task to the current project").argument("<subject>","Task subject").option("--description <text>","Longer task description").option("--tags <tags>","Comma-separated tags").action(async(e,t,n)=>{let{taskAddAction:r}=await Promise.resolve().then(()=>(g1(),h1));return r(e,n)});Foe.command("done").description("Mark a task completed by ID or unique prefix").argument("<id>","Task ID or unique prefix").action(async(e,t,n)=>{let{taskDoneAction:r}=await Promise.resolve().then(()=>(g1(),h1));return r(e,n)});cr.addCommand(Foe);TAt=new Gr("decisions").description("List architectural decisions for the current project").option("--search <query>","Filter decisions by keyword").option("--limit <n>","Maximum number of decisions to show").action(async(e,t)=>{let{decisionsAction:n}=await Promise.resolve().then(()=>(rke(),nke));return n(e,t)});cr.addCommand(TAt);BAt=new Gr("notes").description("List knowledge notes (gotchas, patterns, tips) for the current project").option("--file <path>","Filter notes by file path").option("--type <type>","Filter by type: gotcha, pattern, guideline, tip").option("--status <status>","Filter by status: active, needs_review, stale, obsolete").action(async(e,t)=>{let{notesAction:n}=await Promise.resolve().then(()=>(ike(),oke));return n(e,t)});cr.addCommand(BAt);TNe=new Gr("note").description("Capture project knowledge");TNe.command("add").description("Add a knowledge note").argument("<content>","Note content").option("--file <path>","Related project file",".").option("--title <title>","Short note title").option("--type <type>","gotcha, pattern, guideline, or tip","tip").option("--importance <level>","critical, high, medium, or low","medium").option("--tags <tags>","Comma-separated tags").action(async(e,t,n)=>{let{noteAddAction:r}=await Promise.resolve().then(()=>(g1(),h1));return r(e,n)});cr.addCommand(TNe);BNe=new Gr("decision").description("Capture architectural decisions");BNe.command("add").description("Add a decision").argument("<description>","What was decided").option("--rationale <text>","Why this choice was made").option("--chosen <text>","Chosen option").option("--alternatives <items>","Comma-separated alternatives").option("--tags <tags>","Comma-separated tags").action(async(e,t,n)=>{let{decisionAddAction:r}=await Promise.resolve().then(()=>(g1(),h1));return r(e,n)});cr.addCommand(BNe);RAt=new Gr("doctor").description("Diagnose project identity, sessions, accounts, providers, and dependencies").action(async(e,t)=>{let{doctorAction:n}=await Promise.resolve().then(()=>(ake(),ske));return n(e,t)});cr.addCommand(RAt);$At=new Gr("today").description("Show a cache-only daily brief for this project").action(async(e,t)=>{let{todayAction:n}=await Promise.resolve().then(()=>(dke(),lke));return n(e,t)});cr.addCommand($At);MAt=new Gr("mcp").description("Serve read-only Sidekick facts over MCP stdio").action(async(e,t)=>{let{mcpAction:n}=await Promise.resolve().then(()=>(uOe(),cOe));return n(e,t)});cr.addCommand(MAt);QAt=new Gr("stats").description("Show historical usage stats (tokens, costs, models, tools)").option("--csv","Print every recorded day as CSV (date, sessions, tokens, cost)").action(async(e,t)=>{let{statsAction:n}=await Promise.resolve().then(()=>(mOe(),pOe));return n(e,t)});cr.addCommand(QAt);OAt=new Gr("blocks").description("Show five-hour billing blocks computed from session logs").option("--active","Only the block that is open right now").option("--recent","Blocks from the last three days (default)").option("--since <time>","Blocks since an ISO date, YYYY-MM-DD, or a relative window such as 7d or 24h").option("--csv","Print blocks as CSV").option("--no-cache","Re-read every session instead of using the usage cache").addHelpText("after",zse).action(async(e,t)=>{let{blocksAction:n}=await Promise.resolve().then(()=>(vOe(),yOe));return n(e,t)});cr.addCommand(OAt);cr.addCommand(xj("daily","Daily usage from session logs (default: last 30 days)").action(async(e,t)=>{let{dailyAction:n}=await Promise.resolve().then(()=>(pw(),XR));return n(e,t)}));cr.addCommand(xj("weekly","Weekly usage from session logs (default: last 12 weeks)").action(async(e,t)=>{let{weeklyAction:n}=await Promise.resolve().then(()=>(pw(),XR));return n(e,t)}));cr.addCommand(xj("monthly","Monthly usage from session logs (default: last 12 months)").action(async(e,t)=>{let{monthlyAction:n}=await Promise.resolve().then(()=>(pw(),XR));return n(e,t)}));NAt=new Gr("import").description("Import finished sessions from every provider into the history store").option("--since <time>","Only sessions modified after an ISO date, YYYY-MM-DD, or a relative window such as 30d").addHelpText("after",Use).action(async(e,t)=>{let{importAction:n}=await Promise.resolve().then(()=>(DOe(),kOe));return n(e,t)});cr.addCommand(NAt);cr.addCommand(xj("sessions","One row per session from session logs (default: last 30 days)").action(async(e,t)=>{let{sessionsAction:n}=await Promise.resolve().then(()=>(pw(),XR));return n(e,t)}));RNe=new Gr("quota").description("Show quota or rate-limit utilization (auto-detects provider)").addOption(Iye()).option("--all","Show all providers (Claude, Codex, z.ai if active)").option("--refresh","Ask the provider API first instead of reusing a local sample (Codex always queries the API)").addHelpText("after",Pse).action(async(e,t)=>{let{quotaAction:n}=await Promise.resolve().then(()=>(YOe(),KOe));return n(e,t)});RNe.command("history").description("Render a 13-week heatmap of quota utilization for the current workspace").option("--weeks <n>","Weeks of history to render (default: 13, clamped 1-26)","13").addOption(_ye()).option("--workspace <path>","Workspace path used to derive the history scope (default: cwd)").option("--window <window>","Which limit the heatmap shows: 5h (default), 7d, or max (the higher of the two)","5h").option("--csv","Print the daily buckets as CSV instead of a heatmap").action(async(e,t)=>{let{quotaHistoryAction:n}=await Promise.resolve().then(()=>(tNe(),eNe));return n(e,t)});cr.addCommand(RNe);PAt=new Gr("status").description("Show API status (Claude and OpenAI)").action(async(e,t)=>{let{statusAction:n}=await Promise.resolve().then(()=>(oNe(),rNe));return n(e,t)});cr.addCommand(PAt);zAt=new Gr("statusline").description("Render the cache-only one-line agent status footer").action(async()=>{let{statuslineAction:e}=await Promise.resolve().then(()=>(uNe(),cNe));return e()});cr.addCommand(zAt);FAt=new Gr("peak").description("Show whether Claude is currently in peak hours (faster session-limit drain)").addOption(WK()).action(async(e,t)=>{let{peakAction:n}=await Promise.resolve().then(()=>(dNe(),lNe));return n(e,t)});cr.addCommand(FAt);RIe(cr);UAt=new Gr("account").description("Deprecated: use `sidekick accounts`").option("--provider <id>","Provider: claude-code, codex, all, auto (default: claude-code)").option("--add","Save the currently signed-in account").option("--login","Sign in and save a new account").option("--label <name>","Label for the account (required for Codex, optional for Claude)").option("--switch","Switch to the next saved account").option("--switch-to <identifier>","Switch to a specific account by email, label, or id").option("--remove <identifier>","Remove a saved account by email, label, or id").option("-y, --yes","Skip confirmation prompts for destructive actions").option("--force","Alias for --yes").option("--launcher <name>","Create a per-account launcher for the active account").option("--auto-switch <pct|off>","Persist auto-switch quota threshold, or off").action(async(e,t)=>{let{accountAction:n}=await Promise.resolve().then(()=>(mNe(),pNe));return n(e,t)});cr.addCommand(UAt);LAt=new Gr("extract").description("Extract URLs, file paths, commands, and plans from recent sessions").option("--type <types>","Comma list: url, path, command, plan (default: all)").option("--limit <n>","Maximum items per type").option("-i, --interactive","Interactive picker with copy/open actions").addHelpText("after",Lse).action(async(e,t)=>{let{extractAction:n}=await Promise.resolve().then(()=>(DNe(),kNe));return n(e,t)});cr.addCommand(LAt);$Ne=new Gr("handoff").description("Show the latest session handoff document for the current project").action(async(e,t)=>{let{handoffAction:n}=await Promise.resolve().then(()=>(zoe(),Poe));return n(e,t)});$Ne.command("open").description("Open a configured external session-handoff target").option("--url-template <template>","URL with {sessionId}, {provider}, and {projectPath}").option("--session <id>","Override the active session ID").option("--no-open","Render without opening the URL").action(async(e,t)=>{let{externalHandoffAction:n}=await Promise.resolve().then(()=>(zoe(),Poe));return n(e,t)});cr.addCommand($Ne);n$===void 0&&cr.action(()=>{cr.outputHelp()});cr.parseAsync().catch(e=>{process.stderr.write(Dye(e)),process.exitCode=1})});Cl();export{Wi as resolveProvider,t$ as resolveProviderId};
|