Initial commit: SenSu Alpha 0.2.0

- 13-service async plugin framework
- Textual TUI with CLI fallback
- Plugin hot-reload + permission system
- Web management panel (aiohttp)
- Bridge-based inter-module communication
- 10 regression tests

Fixes applied:
- PBKDF2-SHA256 auth (was plain SHA256)
- Auth bypass removed (was allow-all on fail)
- Bare excepts replaced with logged errors
- CatFramework/DreamSu -> SenSu naming unified
- ServiceManager: health checks + startup_order
- Env var credentials (SENSU_ADMIN_PASSWORD etc)
This commit is contained in:
2026-06-10 12:27:14 +08:00
commit e6875f0b4b
78 changed files with 14843 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
window.DashboardModule = {
charts: {},
init: () => {
// 1. 初始化图表实例
window.DashboardModule.charts = {
mem: new MiniChart('chart-mem', '#9ece6a'),
cpu: new MiniChart('chart-cpu', '#7aa2f7'),
net: new MiniChart('chart-net', '#e0af68'),
proc_mem: new MiniChart('chart-proc-mem', '#f7768e')
};
// 2. 获取并填充右侧固定信息 (只获取一次即可,除非重启)
fetchSystemStaticInfo();
// 3. 启动实时数据轮询
fetchDash();
window._dashInterval = setInterval(fetchDash, 2000); // 2秒刷新
},
destroy: () => {
clearInterval(window._dashInterval);
window.DashboardModule.charts = {};
}
};
async function fetchSystemStaticInfo() {
try {
const sys = await fetch('./api/system', {credentials:'include'}).then(r => r.json());
// 硬件信息
if(sys.platform) {
document.getElementById('info-os').textContent = sys.platform.system || '--';
document.getElementById('info-arch').textContent = sys.platform.machine || '--';
document.getElementById('info-env').textContent = sys.platform.env || 'Standard';
}
if(sys.cpu) {
const c = sys.cpu.cores || 0;
document.getElementById('info-cores').textContent = `${c} / ${c}`; // Android下通常逻辑核=物理核
}
if(sys.memory) {
document.getElementById('info-mem-total').textContent = sys.memory.total_gb + ' GB';
}
// 框架信息 (部分需结合 API)
const host = window.location.hostname + (window.location.port ? ':'+window.location.port : '');
document.getElementById('info-addr').textContent = host;
} catch(e) {}
}
async function fetchDash() {
try {
const fw = await fetch('./api/framework', {credentials:'include'}).then(r => r.json());
const sys = await fetch('./api/system', {credentials:'include'}).then(r => r.json());
// --- 左侧动态数据更新 ---
if(fw) {
document.getElementById('d-uptime').textContent = formatUptime(fw.uptime || 0);
document.getElementById('d-plugins').textContent = fw.plugins || 0;
if(document.getElementById('d-ver-badge')) document.getElementById('d-ver-badge').textContent = 'v' + (fw.version||'?');
}
if(sys) {
// 内存
const m = sys.memory?.percent || 0;
document.getElementById('d-mem').textContent = m + '%';
window.DashboardModule.charts.mem.update(m);
// CPU (兼容 Android null 情况)
let cpuVal = sys.cpu?.percent;
if (cpuVal === null || cpuVal === undefined) {
const load = sys.cpu?.load_avg?.[0] || 0;
const cores = sys.cpu?.cores || 1;
cpuVal = Math.min(100, (load / cores) * 100);
}
document.getElementById('d-cpu').textContent = Math.round(cpuVal) + '%';
window.DashboardModule.charts.cpu.update(cpuVal);
// 网络 (RX 总量)
const netRx = sys.network?.rx || 0;
document.getElementById('d-net').textContent = netRx + ' MB';
window.DashboardModule.charts.net.update(netRx); // 图表显示总流量趋势
// 进程内存
const pm = sys.process?.memory_mb || 0;
document.getElementById('d-proc-mem').textContent = pm + ' MB';
window.DashboardModule.charts.proc_mem.update(pm);
// --- 右侧动态数据更新 ---
if(sys.process) {
document.getElementById('info-pid').textContent = sys.process.pid || '--';
}
if(sys.cpu?.load_avg) {
document.getElementById('info-load').textContent = sys.cpu.load_avg[2].toFixed(2);
}
}
} catch(e) { console.warn("Dashboard fetch error", e); }
}
// 辅助:秒数转时间格式
function formatUptime(seconds) {
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = Math.floor(seconds % 60);
return `${h}h ${m}m ${s}s`;
}