@cccarv82/freya 2.3.9 → 2.3.11
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/cli/vis-network.min.js +34 -0
- package/cli/web-ui.js +102 -37
- package/cli/web.js +325 -27
- package/package.json +1 -1
package/cli/web-ui.js
CHANGED
|
@@ -139,14 +139,14 @@
|
|
|
139
139
|
state.chatSessionId = fromLocal;
|
|
140
140
|
return state.chatSessionId;
|
|
141
141
|
}
|
|
142
|
-
} catch {}
|
|
142
|
+
} catch { }
|
|
143
143
|
|
|
144
144
|
const id = (typeof crypto !== 'undefined' && crypto.randomUUID)
|
|
145
145
|
? crypto.randomUUID()
|
|
146
146
|
: ('sess-' + Date.now() + '-' + Math.random().toString(16).slice(2, 8));
|
|
147
147
|
|
|
148
148
|
state.chatSessionId = id;
|
|
149
|
-
try { localStorage.setItem('freya.chatSessionId', id); } catch {}
|
|
149
|
+
try { localStorage.setItem('freya.chatSessionId', id); } catch { }
|
|
150
150
|
return id;
|
|
151
151
|
}
|
|
152
152
|
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
// keep newest in view
|
|
198
198
|
try {
|
|
199
199
|
thread.scrollTop = thread.scrollHeight;
|
|
200
|
-
} catch {}
|
|
200
|
+
} catch { }
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
async function loadChatHistory() {
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
bubble.appendChild(body);
|
|
231
231
|
thread.appendChild(bubble);
|
|
232
232
|
}
|
|
233
|
-
try { thread.scrollTop = thread.scrollHeight; } catch {}
|
|
233
|
+
try { thread.scrollTop = thread.scrollHeight; } catch { }
|
|
234
234
|
}
|
|
235
235
|
} catch {
|
|
236
236
|
// ignore
|
|
@@ -285,7 +285,7 @@
|
|
|
285
285
|
el.innerHTML = renderMarkdown(state.lastText);
|
|
286
286
|
} catch (e) {
|
|
287
287
|
// Fallback: never hide the error/output if markdown rendering breaks
|
|
288
|
-
try { console.error('renderMarkdown failed:', e); } catch {}
|
|
288
|
+
try { console.error('renderMarkdown failed:', e); } catch { }
|
|
289
289
|
el.textContent = state.lastText;
|
|
290
290
|
}
|
|
291
291
|
}
|
|
@@ -367,9 +367,9 @@
|
|
|
367
367
|
|
|
368
368
|
function saveLocal() {
|
|
369
369
|
localStorage.setItem('freya.dir', $('dir').value);
|
|
370
|
-
try { localStorage.setItem('freya.autoApply', state.autoApply ? '1' : '0'); } catch {}
|
|
371
|
-
try { localStorage.setItem('freya.autoRunReports', state.autoRunReports ? '1' : '0'); } catch {}
|
|
372
|
-
try { localStorage.setItem('freya.prettyPublish', state.prettyPublish ? '1' : '0'); } catch {}
|
|
370
|
+
try { localStorage.setItem('freya.autoApply', state.autoApply ? '1' : '0'); } catch { }
|
|
371
|
+
try { localStorage.setItem('freya.autoRunReports', state.autoRunReports ? '1' : '0'); } catch { }
|
|
372
|
+
try { localStorage.setItem('freya.prettyPublish', state.prettyPublish ? '1' : '0'); } catch { }
|
|
373
373
|
}
|
|
374
374
|
|
|
375
375
|
function loadLocal() {
|
|
@@ -388,7 +388,7 @@
|
|
|
388
388
|
if (v3 !== null) state.prettyPublish = v3 === '1';
|
|
389
389
|
const cb3 = $('prettyPublish');
|
|
390
390
|
if (cb3) cb3.checked = !!state.prettyPublish;
|
|
391
|
-
} catch {}
|
|
391
|
+
} catch { }
|
|
392
392
|
|
|
393
393
|
const def = (window.__FREYA_DEFAULT_DIR && window.__FREYA_DEFAULT_DIR !== '__FREYA_DEFAULT_DIR__')
|
|
394
394
|
? window.__FREYA_DEFAULT_DIR
|
|
@@ -655,7 +655,8 @@
|
|
|
655
655
|
};
|
|
656
656
|
}
|
|
657
657
|
|
|
658
|
-
grid.appendChild(card);
|
|
658
|
+
grid.appendChild(card);
|
|
659
|
+
}
|
|
659
660
|
}
|
|
660
661
|
|
|
661
662
|
function renderProjects() {
|
|
@@ -664,7 +665,7 @@
|
|
|
664
665
|
const filter = String(($('projectsFilter') && $('projectsFilter').value) || '').toLowerCase();
|
|
665
666
|
const items = Array.isArray(state.projects) ? state.projects : [];
|
|
666
667
|
const filtered = items.filter((p) => {
|
|
667
|
-
const hay = [p.client, p.program, p.stream, p.project, p.slug, (p.tags||[]).join(' ')].join(' ').toLowerCase();
|
|
668
|
+
const hay = [p.client, p.program, p.stream, p.project, p.slug, (p.tags || []).join(' ')].join(' ').toLowerCase();
|
|
668
669
|
return !filter || hay.includes(filter);
|
|
669
670
|
});
|
|
670
671
|
el.innerHTML = '';
|
|
@@ -847,9 +848,9 @@
|
|
|
847
848
|
const c = cards[idx];
|
|
848
849
|
const card = document.createElement('div');
|
|
849
850
|
card.className = 'reportCard';
|
|
850
|
-
const dateLine = c.body.find((b)=> b.toLowerCase().includes('data'));
|
|
851
|
-
const impactLine = c.body.find((b)=> b.toLowerCase().includes('descricao') || b.toLowerCase().includes('impacto'));
|
|
852
|
-
const statusLine = c.body.find((b)=> /^status\s*:/i.test(b));
|
|
851
|
+
const dateLine = c.body.find((b) => b.toLowerCase().includes('data'));
|
|
852
|
+
const impactLine = c.body.find((b) => b.toLowerCase().includes('descricao') || b.toLowerCase().includes('impacto'));
|
|
853
|
+
const statusLine = c.body.find((b) => /^status\s*:/i.test(b));
|
|
853
854
|
const statusRaw = statusLine ? statusLine.split(':').slice(1).join(':').trim().toLowerCase() : '';
|
|
854
855
|
let statusKey = '';
|
|
855
856
|
if (['open', 'aberto', 'aberta'].includes(statusRaw)) statusKey = 'open';
|
|
@@ -859,7 +860,7 @@
|
|
|
859
860
|
card.innerHTML = '<div class="reportTitle">' + escapeHtml(c.title) + '</div>'
|
|
860
861
|
+ (dateLine ? ('<div class="reportMeta">' + escapeHtml(dateLine) + '</div>') : '')
|
|
861
862
|
+ (impactLine ? ('<div class="help" style="margin-top:4px">' + escapeHtml(impactLine) + '</div>') : '')
|
|
862
|
-
+ c.body.filter((b)=> b!==dateLine && b!==impactLine && b!==statusLine).map((b) => '<div class="help" style="margin-top:4px">' + escapeHtml(b) + '</div>').join('');
|
|
863
|
+
+ c.body.filter((b) => b !== dateLine && b !== impactLine && b !== statusLine).map((b) => '<div class="help" style="margin-top:4px">' + escapeHtml(b) + '</div>').join('');
|
|
863
864
|
|
|
864
865
|
if (statusKey) {
|
|
865
866
|
const actions = document.createElement('div');
|
|
@@ -913,7 +914,7 @@
|
|
|
913
914
|
el.innerHTML = '';
|
|
914
915
|
let items = r.items || [];
|
|
915
916
|
const sort = state.heatmapSort || 'pending';
|
|
916
|
-
items = items.slice().sort((a,b)=> (b[sort]||0) - (a[sort]||0));
|
|
917
|
+
items = items.slice().sort((a, b) => (b[sort] || 0) - (a[sort] || 0));
|
|
917
918
|
for (const it of items) {
|
|
918
919
|
const row = document.createElement('div');
|
|
919
920
|
row.className = 'rep';
|
|
@@ -1001,6 +1002,12 @@
|
|
|
1001
1002
|
if (!isTimeline) window.location.href = '/timeline';
|
|
1002
1003
|
};
|
|
1003
1004
|
}
|
|
1005
|
+
if ($('railGraph')) {
|
|
1006
|
+
$('railGraph').onclick = () => {
|
|
1007
|
+
const isGraph = document.body && document.body.dataset && document.body.dataset.page === 'graph';
|
|
1008
|
+
if (!isGraph) window.location.href = '/graph';
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1004
1011
|
if (health) {
|
|
1005
1012
|
health.onclick = () => {
|
|
1006
1013
|
const isHealth = document.body && document.body.dataset && document.body.dataset.page === 'companion';
|
|
@@ -1172,7 +1179,7 @@
|
|
|
1172
1179
|
if (r && r.dir) {
|
|
1173
1180
|
$('dir').value = r.dir;
|
|
1174
1181
|
const sp = $('sidePath');
|
|
1175
|
-
|
|
1182
|
+
if (sp) sp.textContent = r.dir;
|
|
1176
1183
|
}
|
|
1177
1184
|
saveLocal();
|
|
1178
1185
|
setPill('ok', 'ready');
|
|
@@ -1194,7 +1201,7 @@
|
|
|
1194
1201
|
setLast(null);
|
|
1195
1202
|
await refreshReports({ selectLatest: true });
|
|
1196
1203
|
// Auto health after init
|
|
1197
|
-
try { await doHealth(); } catch {}
|
|
1204
|
+
try { await doHealth(); } catch { }
|
|
1198
1205
|
setPill('ok', 'init ok');
|
|
1199
1206
|
} catch (e) {
|
|
1200
1207
|
setPill('err', 'init failed');
|
|
@@ -1215,7 +1222,7 @@
|
|
|
1215
1222
|
setLast(null);
|
|
1216
1223
|
await refreshReports({ selectLatest: true });
|
|
1217
1224
|
// Auto health after update
|
|
1218
|
-
try { await doHealth(); } catch {}
|
|
1225
|
+
try { await doHealth(); } catch { }
|
|
1219
1226
|
setPill('ok', 'update ok');
|
|
1220
1227
|
} catch (e) {
|
|
1221
1228
|
setPill('err', 'update failed');
|
|
@@ -1303,11 +1310,11 @@
|
|
|
1303
1310
|
}
|
|
1304
1311
|
}
|
|
1305
1312
|
|
|
1306
|
-
async function
|
|
1307
|
-
const el = $('
|
|
1308
|
-
if (el) el.innerHTML = '<div class="help">
|
|
1313
|
+
async function refreshRiskRadar() {
|
|
1314
|
+
const el = $('riskRadarBox');
|
|
1315
|
+
if (el) el.innerHTML = '<div class="help">Calculando riscos...</div>';
|
|
1309
1316
|
try {
|
|
1310
|
-
const r = await api('/api/risk
|
|
1317
|
+
const r = await api('/api/companion/risk-radar', { dir: dirOrDefault() });
|
|
1311
1318
|
if (!el) return;
|
|
1312
1319
|
if (r && r.needsInit) {
|
|
1313
1320
|
el.innerHTML = '<div class="help">Workspace não inicializado.</div>';
|
|
@@ -1315,23 +1322,74 @@
|
|
|
1315
1322
|
}
|
|
1316
1323
|
const items = Array.isArray(r.items) ? r.items : [];
|
|
1317
1324
|
if (!items.length) {
|
|
1318
|
-
el.innerHTML = '<div class="help">
|
|
1325
|
+
el.innerHTML = '<div class="help">Radar livre de riscos críticos ou moderados no momento.</div>';
|
|
1319
1326
|
return;
|
|
1320
1327
|
}
|
|
1321
1328
|
const rows = items.map((it) => {
|
|
1322
|
-
const
|
|
1329
|
+
const pillClass = it.severity === 'high' ? 'warn' : 'info';
|
|
1330
|
+
const pillLabel = it.severity === 'high' ? 'Alto Risco' : 'Atenção';
|
|
1323
1331
|
return `<div class=\"rep\">`
|
|
1324
1332
|
+ `<div style=\"display:flex; justify-content:space-between; gap:10px; align-items:center\">`
|
|
1325
1333
|
+ `<div style=\"min-width:0\"><div style=\"font-weight:800\">${escapeHtml(it.slug || '')}</div>`
|
|
1326
|
-
+ `<div class=\"help\" style=\"margin-top:4px\"
|
|
1334
|
+
+ `<div class=\"help\" style=\"margin-top:4px\">${escapeHtml(it.message || '')}</div>`
|
|
1327
1335
|
+ `</div>`
|
|
1328
|
-
+ `<div class=\"pill
|
|
1336
|
+
+ `<div class=\"pill ${pillClass}\">${pillLabel}</div>`
|
|
1329
1337
|
+ `</div>`
|
|
1330
1338
|
+ `</div>`;
|
|
1331
1339
|
}).join('');
|
|
1332
1340
|
el.innerHTML = rows;
|
|
1333
1341
|
} catch {
|
|
1334
|
-
if (el) el.innerHTML = '<div class="help">Falha ao carregar
|
|
1342
|
+
if (el) el.innerHTML = '<div class="help">Falha ao carregar o Radar de Risco.</div>';
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
async function refreshGraph() {
|
|
1347
|
+
try {
|
|
1348
|
+
if (!window.vis) return; // vis.js not loaded yet
|
|
1349
|
+
const el = $('networkGraph');
|
|
1350
|
+
if (!el) return;
|
|
1351
|
+
|
|
1352
|
+
const r = await api('/api/graph/data', { dir: dirOrDefault() });
|
|
1353
|
+
if (!r || !r.nodes) return;
|
|
1354
|
+
|
|
1355
|
+
const nodes = new vis.DataSet(r.nodes);
|
|
1356
|
+
const edges = new vis.DataSet(r.edges);
|
|
1357
|
+
|
|
1358
|
+
const data = { nodes, edges };
|
|
1359
|
+
const options = {
|
|
1360
|
+
nodes: {
|
|
1361
|
+
shape: 'dot',
|
|
1362
|
+
size: 16,
|
|
1363
|
+
font: { color: 'var(--fg)', face: 'var(--sans)' },
|
|
1364
|
+
borderWidth: 2
|
|
1365
|
+
},
|
|
1366
|
+
edges: {
|
|
1367
|
+
color: { color: 'var(--border)', highlight: 'var(--brand)' },
|
|
1368
|
+
width: 1,
|
|
1369
|
+
smooth: { type: 'continuous' }
|
|
1370
|
+
},
|
|
1371
|
+
groups: {
|
|
1372
|
+
project: { color: { background: 'var(--bg2)', border: 'var(--brand)' } },
|
|
1373
|
+
task: { color: { background: 'var(--bg2)', border: 'var(--info)' }, size: 10 },
|
|
1374
|
+
blocker: { color: { background: 'var(--warn-bg)', border: 'var(--warn)' }, size: 14, shape: 'triangle' },
|
|
1375
|
+
tag: { color: { background: 'var(--bg2)', border: 'var(--border)' }, size: 8, font: { size: 10 } },
|
|
1376
|
+
unassigned: { color: { background: 'var(--bg2)', border: 'var(--border)' }, size: 10 }
|
|
1377
|
+
},
|
|
1378
|
+
physics: {
|
|
1379
|
+
forceAtlas2Based: { gravitationalConstant: -26, centralGravity: 0.005, springLength: 230, springConstant: 0.18 },
|
|
1380
|
+
maxVelocity: 146,
|
|
1381
|
+
solver: 'forceAtlas2Based',
|
|
1382
|
+
timestep: 0.35,
|
|
1383
|
+
stabilization: { iterations: 150 }
|
|
1384
|
+
}
|
|
1385
|
+
};
|
|
1386
|
+
|
|
1387
|
+
if (state.networkInstance) {
|
|
1388
|
+
state.networkInstance.destroy();
|
|
1389
|
+
}
|
|
1390
|
+
state.networkInstance = new vis.Network(el, data, options);
|
|
1391
|
+
} catch (e) {
|
|
1392
|
+
console.error('Failed to load graph data', e);
|
|
1335
1393
|
}
|
|
1336
1394
|
}
|
|
1337
1395
|
|
|
@@ -1577,19 +1635,19 @@
|
|
|
1577
1635
|
function togglePrettyPublish() {
|
|
1578
1636
|
const cb = $('prettyPublish');
|
|
1579
1637
|
state.prettyPublish = cb ? !!cb.checked : true;
|
|
1580
|
-
try { localStorage.setItem('freya.prettyPublish', state.prettyPublish ? '1' : '0'); } catch {}
|
|
1638
|
+
try { localStorage.setItem('freya.prettyPublish', state.prettyPublish ? '1' : '0'); } catch { }
|
|
1581
1639
|
}
|
|
1582
1640
|
|
|
1583
1641
|
function toggleAutoRunReports() {
|
|
1584
1642
|
const cb = $('autoRunReports');
|
|
1585
1643
|
state.autoRunReports = cb ? !!cb.checked : false;
|
|
1586
|
-
try { localStorage.setItem('freya.autoRunReports', state.autoRunReports ? '1' : '0'); } catch {}
|
|
1644
|
+
try { localStorage.setItem('freya.autoRunReports', state.autoRunReports ? '1' : '0'); } catch { }
|
|
1587
1645
|
}
|
|
1588
1646
|
|
|
1589
1647
|
function toggleAutoApply() {
|
|
1590
1648
|
const cb = $('autoApply');
|
|
1591
1649
|
state.autoApply = cb ? !!cb.checked : true;
|
|
1592
|
-
try { localStorage.setItem('freya.autoApply', state.autoApply ? '1' : '0'); } catch {}
|
|
1650
|
+
try { localStorage.setItem('freya.autoApply', state.autoApply ? '1' : '0'); } catch { }
|
|
1593
1651
|
}
|
|
1594
1652
|
|
|
1595
1653
|
async function saveAndPlan() {
|
|
@@ -1699,8 +1757,8 @@
|
|
|
1699
1757
|
chatAppend('assistant', msg, { markdown: true });
|
|
1700
1758
|
|
|
1701
1759
|
// After apply, refresh panels so the UI reflects the new state (tasks/blockers/reports)
|
|
1702
|
-
try { await refreshToday(); } catch {}
|
|
1703
|
-
try { await refreshReports({ selectLatest: true }); } catch {}
|
|
1760
|
+
try { await refreshToday(); } catch { }
|
|
1761
|
+
try { await refreshReports({ selectLatest: true }); } catch { }
|
|
1704
1762
|
|
|
1705
1763
|
setPill('ok', 'applied');
|
|
1706
1764
|
setTimeout(() => setPill('ok', 'pronto'), 800);
|
|
@@ -1725,15 +1783,16 @@
|
|
|
1725
1783
|
const open = localStorage.getItem('freya.devDrawer') === '1';
|
|
1726
1784
|
if (open) d.open = true;
|
|
1727
1785
|
d.addEventListener('toggle', () => {
|
|
1728
|
-
try { localStorage.setItem('freya.devDrawer', d.open ? '1' : '0'); } catch {}
|
|
1786
|
+
try { localStorage.setItem('freya.devDrawer', d.open ? '1' : '0'); } catch { }
|
|
1729
1787
|
});
|
|
1730
1788
|
}
|
|
1731
|
-
} catch {}
|
|
1789
|
+
} catch { }
|
|
1732
1790
|
|
|
1733
1791
|
const isReportsPage = document.body && document.body.dataset && document.body.dataset.page === 'reports';
|
|
1734
1792
|
const isProjectsPage = document.body && document.body.dataset && document.body.dataset.page === 'projects';
|
|
1735
1793
|
const isTimelinePage = document.body && document.body.dataset && document.body.dataset.page === 'timeline';
|
|
1736
1794
|
const isCompanionPage = document.body && document.body.dataset && document.body.dataset.page === 'companion';
|
|
1795
|
+
const isGraphPage = document.body && document.body.dataset && document.body.dataset.page === 'graph';
|
|
1737
1796
|
|
|
1738
1797
|
// Load persisted settings from the workspace + bootstrap (auto-init + auto-health)
|
|
1739
1798
|
(async () => {
|
|
@@ -1771,12 +1830,17 @@
|
|
|
1771
1830
|
return;
|
|
1772
1831
|
}
|
|
1773
1832
|
|
|
1833
|
+
if (isGraphPage) {
|
|
1834
|
+
await refreshGraph();
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1774
1838
|
if (isCompanionPage) {
|
|
1775
1839
|
await refreshHealthChecklist();
|
|
1776
1840
|
await refreshQualityScore();
|
|
1777
1841
|
await refreshExecutiveSummary();
|
|
1778
1842
|
await refreshAnomalies();
|
|
1779
|
-
await
|
|
1843
|
+
await refreshRiskRadar();
|
|
1780
1844
|
await refreshIncidents();
|
|
1781
1845
|
await refreshHeatmap();
|
|
1782
1846
|
return;
|
|
@@ -1822,6 +1886,7 @@
|
|
|
1822
1886
|
window.refreshReportsPage = refreshReportsPage;
|
|
1823
1887
|
window.refreshProjects = refreshProjects;
|
|
1824
1888
|
window.refreshTimeline = refreshTimeline;
|
|
1889
|
+
window.refreshGraph = refreshGraph;
|
|
1825
1890
|
window.refreshIncidents = refreshIncidents;
|
|
1826
1891
|
window.refreshHeatmap = refreshHeatmap;
|
|
1827
1892
|
window.setHeatmapSort = setHeatmapSort;
|
|
@@ -1831,7 +1896,7 @@
|
|
|
1831
1896
|
window.refreshQualityScore = refreshQualityScore;
|
|
1832
1897
|
window.refreshExecutiveSummary = refreshExecutiveSummary;
|
|
1833
1898
|
window.refreshAnomalies = refreshAnomalies;
|
|
1834
|
-
window.
|
|
1899
|
+
window.refreshRiskRadar = refreshRiskRadar;
|
|
1835
1900
|
window.copyOut = copyOut;
|
|
1836
1901
|
window.copyPath = copyPath;
|
|
1837
1902
|
window.openSelected = openSelected;
|