MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / gatherDashboardData

Function gatherDashboardData

src/cli/dashboard.ts:290–459  ·  view source on GitHub ↗
(cwd: string)

Source from the content-addressed store, hash-verified

288 function toast(msg, ok){ const t=document.getElementById('toast'); t.textContent=msg; t.style.borderColor=ok?'var(--green)':'#ff6b6b'; t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),2600); }
289 async function act(action, params){
290 try{
291 const r = await fetch('/api/action?k='+encodeURIComponent(TOKEN),{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({action,params})});
292 const j = await r.json();
293 toast(j.message || (j.ok?'Done':'Failed'), j.ok);
294 if(j.ok) setTimeout(()=>location.reload(), 700);
295 }catch(e){ toast(String(e), false); }
296 }
297 async function recallRun(){
298 const q = document.getElementById('recall-q').value.trim();
299 if(!q) return;
300 const out = document.getElementById('recall-out');
301 out.style.display = 'block'; out.textContent = 'Searching your history…';
302 try{
303 const r = await fetch('/api/action?k='+encodeURIComponent(TOKEN),{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({action:'recall.query',params:{query:q}})});
304 const j = await r.json();
305 out.textContent = j.message || (j.ok ? '(no result)' : 'Failed');
306 }catch(e){ out.textContent = String(e); }
307 }
308` : ''}
309</script></body></html>`;
310}
311
312/** Gather the dashboard's data from the live stores + config. Defensive — a missing source is empty. */
313export async function gatherDashboardData(cwd: string): Promise<DashboardData> {
314 const { loadConfig } = await import('../config/loader.js');
315 const { getSessionStore } = await import('../session/store.js');
316 const config: any = await loadConfig(cwd).catch(() => ({ defaults: {}, providers: {} }));
317 const store = getSessionStore();
318
319 const project = (() => { try { return store.getProject(cwd)?.name || path.basename(cwd); } catch { return path.basename(cwd); } })();
320 const defModel = config?.defaults?.model ?? '(unset)';
321 const defProvider = config?.defaults?.provider;
322 const roleModels = await (async () => {
323 try {
324 const { looksVisionCapable } = await import('../setup/model-detector.js');
325 return {
326 subagent: config?.roles?.subagent?.model as string | undefined,
327 vision: config?.roles?.vision?.model as string | undefined,
328 mainHasVision: typeof defModel === 'string' && looksVisionCapable(defModel),
329 };
330 } catch { return { subagent: undefined, vision: undefined, mainHasVision: false }; }
331 })();
332
333 // Providers: built-ins present in config + user customs.
334 const providers: DashboardData['providers'] = [];
335 const pcfg = config?.providers ?? {};
336 for (const [name, v] of Object.entries<any>(pcfg)) {
337 if (name === 'custom') continue;
338 providers.push({
339 name, baseUrl: v?.baseUrl ?? '', keyEnv: v?.apiKeyEnv,
340 keySet: v?.apiKeyEnv ? !!process.env[v.apiKeyEnv] : undefined,
341 models: (v?.extraModels ?? []).map((m: any) => m.id).filter(Boolean),
342 isDefault: name === defProvider,
343 });
344 }
345 for (const c of (pcfg.custom ?? [])) {
346 providers.push({
347 name: c.name, baseUrl: c.baseUrl ?? '', keyEnv: c.apiKeyEnv,

Callers 3

dashboard.test.tsFile · 0.90
runDashboardFunction · 0.85
writeStaticDashboardFunction · 0.85

Calls 15

loadConfigFunction · 0.85
getSessionStoreFunction · 0.85
looksVisionCapableFunction · 0.85
readEpisodesFunction · 0.85
loadSkillsFunction · 0.85
getDeepFunction · 0.85
getScheduleStoreFunction · 0.85
listCandidatesFunction · 0.85
parseMaintainScopeFunction · 0.85
buildMaintainStatsFunction · 0.85
weeklyReportFunction · 0.85
recommendNextScopeFunction · 0.85

Tested by

no test coverage detected