From 164c6bcad0a12a8bcdb3e83d8955cf83547ada9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Virg=C3=ADlio=20Santos?= Date: Sat, 14 Mar 2026 15:27:27 -0300 Subject: [PATCH 1/4] =?UTF-8?q?Added=20.nvmrc=20=E2=80=94=20pin=20Node=202?= =?UTF-8?q?2=20and=20npm=20>=3D10=20engine=20requirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .nvmrc | 1 + package.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22 diff --git a/package.json b/package.json index 2ac3593..f21b41b 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "author": "Crucix", "license": "ISC", "engines": { - "node": ">=22" + "node": ">=22", + "npm": ">=10" }, "dependencies": { "express": "^5.1.0" From 15b45681402ff4bc1f46390dddd0db53d7e86367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Virg=C3=ADlio=20Santos?= Date: Sat, 14 Mar 2026 15:33:34 -0300 Subject: [PATCH 2/4] =?UTF-8?q?Added=20start=20script=20=E2=80=94=20clean?= =?UTF-8?q?=20production=20entry=20point=20for=20server.mjs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index f21b41b..1197dc9 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Local intelligence engine — 26 OSINT sources, live dashboard, auto-refresh, optional LLM layer.", "type": "module", "scripts": { + "start": "node server.mjs", "dev": "node --trace-warnings server.mjs", "sweep": "node apis/briefing.mjs", "inject": "node dashboard/inject.mjs", From 1933e063ae39c9423e9236db8d971f2f44e10b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Virg=C3=ADlio=20Santos?= Date: Sat, 14 Mar 2026 15:47:09 -0300 Subject: [PATCH 3/4] =?UTF-8?q?Added=20loading=20page=20=E2=80=94=20SSE-dr?= =?UTF-8?q?iven=20splash=20screen=20for=20first-run=20UX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/public/jarvis.html | 10 +--- dashboard/public/loading.html | 103 ++++++++++++++++++++++++++++++++++ package.json | 4 +- server.mjs | 8 ++- 4 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 dashboard/public/loading.html diff --git a/dashboard/public/jarvis.html b/dashboard/public/jarvis.html index d12e2ed..59e2500 100644 --- a/dashboard/public/jarvis.html +++ b/dashboard/public/jarvis.html @@ -1058,14 +1058,8 @@ document.addEventListener('DOMContentLoaded', () => { .then(r => r.json()) .then(data => { D = data; init(); connectSSE(); }) .catch(() => { - // API not ready yet — use inline data as fallback if available - if (D && D.meta) { init(); } - else { document.getElementById('bootLines').innerHTML = '
Waiting for first sweep...
'; } - // Retry after a delay - setTimeout(() => { - fetch('/api/data').then(r => r.json()).then(data => { D = data; init(); connectSSE(); }).catch(() => {}); - }, 10000); - connectSSE(); + // Should not reach here — server routes to loading.html when no data + if (D && D.meta) { init(); connectSSE(); } }); } else if (D && D.meta) { // File mode: use inline data diff --git a/dashboard/public/loading.html b/dashboard/public/loading.html new file mode 100644 index 0000000..ebb0084 --- /dev/null +++ b/dashboard/public/loading.html @@ -0,0 +1,103 @@ + + + + + +CRUCIX — Initializing + + + + + +
+
+ CX +
+ +
+ +
COLLECTING DATA...
+
+ + + + diff --git a/package.json b/package.json index 1197dc9..5d9085e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "inject": "node dashboard/inject.mjs", "brief": "node apis/briefing.mjs", "brief:save": "node apis/save-briefing.mjs", - "diag": "node diag.mjs" + "diag": "node diag.mjs", + "clean": "node scripts/clean.mjs", + "fresh-start": "npm run clean && npm start" }, "keywords": ["osint", "intelligence", "dashboard", "geopolitical"], "author": "Crucix", diff --git a/server.mjs b/server.mjs index f6173f2..96643da 100644 --- a/server.mjs +++ b/server.mjs @@ -230,9 +230,13 @@ if (discordAlerter.isConfigured) { const app = express(); app.use(express.static(join(ROOT, 'dashboard/public'))); -// Serve jarvis.html as the root page +// Serve loading page until first sweep completes, then the dashboard app.get('/', (req, res) => { - res.sendFile(join(ROOT, 'dashboard/public/jarvis.html')); + if (!currentData) { + res.sendFile(join(ROOT, 'dashboard/public/loading.html')); + } else { + res.sendFile(join(ROOT, 'dashboard/public/jarvis.html')); + } }); // API: current data From 4c601ed1424eafb2c10b104e9997256f1507021b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Virg=C3=ADlio=20Santos?= Date: Sat, 14 Mar 2026 15:53:55 -0300 Subject: [PATCH 4/4] =?UTF-8?q?Added=20countdown=20timer=20to=20loading=20?= =?UTF-8?q?page=20=E2=80=94=20progress=20bar=20with=20sweep=20ETA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dashboard/public/loading.html | 67 ++++++++++++++++++++++++++++++----- scripts/clean.mjs | 18 ++++++++++ server.mjs | 5 ++- 3 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 scripts/clean.mjs diff --git a/dashboard/public/loading.html b/dashboard/public/loading.html index ebb0084..196f6ab 100644 --- a/dashboard/public/loading.html +++ b/dashboard/public/loading.html @@ -22,15 +22,19 @@ html,body{height:100%;background:var(--bg);color:var(--text);font-family:var(--m @keyframes fadein{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}} .logo-text{font-size:18px;font-weight:700;letter-spacing:0.2em;color:var(--accent)} - .container{display:flex;flex-direction:column;align-items:center;gap:32px} #bootLines{font-size:12px;color:var(--dim);text-align:left;line-height:2;min-width:340px} #bootLines .line{opacity:0;animation:fadein 0.3s ease forwards} #bootLines .ok{color:var(--accent)} -#status{font-size:12px;color:var(--accent);letter-spacing:0.15em;margin-top:4px;min-height:20px} -#status .blink{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);animation:pulse-blink 1.5s ease-in-out infinite;vertical-align:middle;margin-right:8px} +#status{font-size:12px;color:var(--accent);letter-spacing:0.15em;margin-top:4px;min-height:20px;display:flex;align-items:center;gap:8px} +#status .blink{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);animation:pulse-blink 1.5s ease-in-out infinite;flex-shrink:0} + +#countdown{margin-top:8px;font-size:11px;color:var(--dim);letter-spacing:0.1em;text-align:center;min-height:16px} +#countdown .eta{color:var(--text)} +#countdown .bar-wrap{width:340px;height:2px;background:rgba(100,240,200,0.08);margin-top:8px;overflow:hidden} +#countdown .bar-fill{height:100%;background:var(--accent);width:0%;transition:width 1s linear;box-shadow:0 0 6px var(--accent)} @@ -41,10 +45,20 @@ html,body{height:100%;background:var(--bg);color:var(--text);font-family:var(--m
-
COLLECTING DATA...
+
+ + COLLECTING DATA... +
+ +
+ +
+