feat: add info engine MVP pipeline and dashboard page
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 2m10s

Introduce a standalone scheduled info-engine worker with SQLite persistence and expose read-only dashboard APIs/UI so curated intelligence items can be collected and viewed with minimal architecture changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gan, Jimmy
2026-03-02 23:35:10 +08:00
parent 14965c7e03
commit a91a1132c9
15 changed files with 602 additions and 2 deletions
@@ -4,7 +4,9 @@
function canAccess(id) {
if (!id) return true;
if (allowedPages === "*") return true;
return Array.isArray(allowedPages) && allowedPages.includes(id);
if (!Array.isArray(allowedPages)) return false;
if (id === "info-engine") return allowedPages.includes("dashboard");
return allowedPages.includes(id);
}
function canSeeSidebarLink(item) {
@@ -16,6 +18,7 @@
const defaultLinks = [
{ id: "dashboard", label: "Overview", icon: "grid" },
{ id: "info-engine", label: "Info Engine", icon: "sparkles" },
{ id: "litellm", label: "LiteLLM", icon: "bolt" },
{ id: "docker", label: "Docker", icon: "box" },
{ id: "files", label: "Files", icon: "folder" },
@@ -228,6 +231,8 @@
<span class="w-5 h-5 flex items-center justify-center">
{#if icon === "grid"}
<svg class="w-[18px] h-[18px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8"><path stroke-linecap="round" stroke-linejoin="round" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zm10 0a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zm10 0a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" /></svg>
{:else if icon === "sparkles"}
<svg class="w-[18px] h-[18px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3l1.8 4.2L18 9l-4.2 1.8L12 15l-1.8-4.2L6 9l4.2-1.8L12 3zm6 11l.9 2.1L21 17l-2.1.9L18 20l-.9-2.1L15 17l2.1-.9L18 14zM5 14l.9 2.1L8 17l-2.1.9L5 20l-.9-2.1L2 17l2.1-.9L5 14z" /></svg>
{:else if icon === "box"}
<svg class="w-[18px] h-[18px]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8"><path stroke-linecap="round" stroke-linejoin="round" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" /></svg>
{:else if icon === "bolt"}