seo-intel 1.1.0 → 1.1.2
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/README.md +1 -1
- package/Setup SEO Intel.command +21 -5
- package/package.json +1 -1
- package/reports/generate-html.js +61 -0
- package/server.js +15 -0
- package/setup/openclaw-bridge.js +1 -1
package/README.md
CHANGED
package/Setup SEO Intel.command
CHANGED
|
@@ -2,10 +2,26 @@
|
|
|
2
2
|
cd "$(dirname "$0")" || cd ~
|
|
3
3
|
clear
|
|
4
4
|
echo ""
|
|
5
|
-
echo " SEO Intel — Setup Wizard"
|
|
6
|
-
echo "
|
|
5
|
+
echo " 🦀 SEO Intel — Setup Wizard"
|
|
6
|
+
echo " Opening in your browser..."
|
|
7
7
|
echo ""
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
# Start server in background if not already running
|
|
10
|
+
if ! curl -s http://localhost:3000/ > /dev/null 2>&1; then
|
|
11
|
+
npx seo-intel serve &
|
|
12
|
+
SERVER_PID=$!
|
|
13
|
+
sleep 2
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# Open setup wizard in browser
|
|
17
|
+
open "http://localhost:3000/setup" 2>/dev/null || xdg-open "http://localhost:3000/setup" 2>/dev/null
|
|
18
|
+
|
|
19
|
+
echo " Setup wizard is open at http://localhost:3000/setup"
|
|
20
|
+
echo " Keep this window open while using the wizard."
|
|
9
21
|
echo ""
|
|
10
|
-
|
|
11
|
-
|
|
22
|
+
read -n 1 -s -r -p " Press any key to stop the server and exit..."
|
|
23
|
+
|
|
24
|
+
# Clean up
|
|
25
|
+
if [ -n "$SERVER_PID" ]; then
|
|
26
|
+
kill $SERVER_PID 2>/dev/null
|
|
27
|
+
fi
|
package/package.json
CHANGED
package/reports/generate-html.js
CHANGED
|
@@ -261,6 +261,44 @@ function buildHtmlTemplate(data, opts = {}) {
|
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
/* ─── Header Bar ─────────────────────────────────────────────────────── */
|
|
264
|
+
.update-banner {
|
|
265
|
+
padding: 10px 20px;
|
|
266
|
+
border-radius: var(--radius);
|
|
267
|
+
display: flex;
|
|
268
|
+
align-items: center;
|
|
269
|
+
gap: 12px;
|
|
270
|
+
font-size: 0.78rem;
|
|
271
|
+
margin-bottom: 12px;
|
|
272
|
+
}
|
|
273
|
+
.update-banner.update-normal {
|
|
274
|
+
background: rgba(232,213,163,0.06);
|
|
275
|
+
border: 1px solid rgba(232,213,163,0.2);
|
|
276
|
+
color: var(--accent-gold);
|
|
277
|
+
}
|
|
278
|
+
.update-banner.update-security {
|
|
279
|
+
background: rgba(220,80,80,0.08);
|
|
280
|
+
border: 1px solid rgba(220,80,80,0.25);
|
|
281
|
+
color: #ff6b6b;
|
|
282
|
+
}
|
|
283
|
+
.update-banner .update-version { font-family: var(--font-mono); font-weight: 600; }
|
|
284
|
+
.update-banner .update-changelog { font-size: 0.68rem; color: var(--text-muted); flex:1; }
|
|
285
|
+
.update-banner .update-btn {
|
|
286
|
+
padding: 5px 14px;
|
|
287
|
+
border-radius: 6px;
|
|
288
|
+
font-size: 0.7rem;
|
|
289
|
+
font-weight: 600;
|
|
290
|
+
border: 1px solid currentColor;
|
|
291
|
+
background: transparent;
|
|
292
|
+
color: inherit;
|
|
293
|
+
cursor: pointer;
|
|
294
|
+
white-space: nowrap;
|
|
295
|
+
}
|
|
296
|
+
.update-banner .update-btn:hover { background: rgba(255,255,255,0.06); }
|
|
297
|
+
.update-banner .update-dismiss {
|
|
298
|
+
cursor: pointer; opacity: 0.5; font-size: 0.7rem;
|
|
299
|
+
}
|
|
300
|
+
.update-banner .update-dismiss:hover { opacity: 1; }
|
|
301
|
+
|
|
264
302
|
.header-bar {
|
|
265
303
|
background: var(--bg-card);
|
|
266
304
|
border: 1px solid var(--border-card);
|
|
@@ -1795,6 +1833,8 @@ function buildHtmlTemplate(data, opts = {}) {
|
|
|
1795
1833
|
// ── Panel HTML (project-specific body content) ──
|
|
1796
1834
|
const panelHtml = `
|
|
1797
1835
|
<div class="project-panel" data-project="${project}">
|
|
1836
|
+
<!-- UPDATE BANNER (populated by JS if update available) -->
|
|
1837
|
+
<div id="updateBanner${suffix}" style="display:none;"></div>
|
|
1798
1838
|
<!-- HEADER BAR -->
|
|
1799
1839
|
<div class="header-bar" id="header">
|
|
1800
1840
|
<div class="header-left">
|
|
@@ -3405,6 +3445,27 @@ function buildHtmlTemplate(data, opts = {}) {
|
|
|
3405
3445
|
bg: '#111111', grid: '#222222', text: '#b8b8b8', muted: '#555555'
|
|
3406
3446
|
};
|
|
3407
3447
|
|
|
3448
|
+
// ═══ UPDATE CHECK ═══
|
|
3449
|
+
(function() {
|
|
3450
|
+
if (!window.location.protocol.startsWith('http')) return;
|
|
3451
|
+
fetch('/api/update-check').then(r => r.json()).then(function(info) {
|
|
3452
|
+
if (!info.hasUpdate) return;
|
|
3453
|
+
var banner = document.getElementById('updateBanner${suffix}');
|
|
3454
|
+
if (!banner) return;
|
|
3455
|
+
var cls = info.security ? 'update-security' : 'update-normal';
|
|
3456
|
+
var icon = info.security ? 'fa-shield-halved' : 'fa-arrow-up';
|
|
3457
|
+
var changelogHtml = info.changelog ? '<span class="update-changelog">' + info.changelog.split('\\n')[0] + '</span>' : '';
|
|
3458
|
+
banner.style.display = 'block';
|
|
3459
|
+
banner.innerHTML = '<div class="update-banner ' + cls + '">' +
|
|
3460
|
+
'<i class="fa-solid ' + icon + '"></i>' +
|
|
3461
|
+
'<span class="update-version">' + info.current + ' → ' + info.latest + '</span>' +
|
|
3462
|
+
changelogHtml +
|
|
3463
|
+
'<button class="update-btn" onclick="navigator.clipboard.writeText(\\'npm update -g seo-intel\\');this.textContent=\\'Copied!\\';setTimeout(()=>this.textContent=\\'Update\\',2000)">Update</button>' +
|
|
3464
|
+
'<span class="update-dismiss" onclick="this.closest(\\'.update-banner\\').style.display=\\'none\\'"><i class="fa-solid fa-xmark"></i></span>' +
|
|
3465
|
+
'</div>';
|
|
3466
|
+
}).catch(function() {});
|
|
3467
|
+
})();
|
|
3468
|
+
|
|
3408
3469
|
// ═══ LIVE DASHBOARD CONTROLS ═══
|
|
3409
3470
|
(function() {
|
|
3410
3471
|
const isServed = window.location.protocol.startsWith('http');
|
package/server.js
CHANGED
|
@@ -3,6 +3,7 @@ import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
|
|
|
3
3
|
import { spawn } from 'child_process';
|
|
4
4
|
import { dirname, join, extname } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
+
import { checkForUpdates, getUpdateInfo } from './lib/updater.js';
|
|
6
7
|
|
|
7
8
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
9
|
const PORT = parseInt(process.env.PORT || '3000', 10);
|
|
@@ -325,6 +326,17 @@ async function handleRequest(req, res) {
|
|
|
325
326
|
|
|
326
327
|
|
|
327
328
|
// ─── API: Stop running job ───
|
|
329
|
+
// ─── API: Update check ───
|
|
330
|
+
if (req.method === 'GET' && path === '/api/update-check') {
|
|
331
|
+
try {
|
|
332
|
+
const info = await getUpdateInfo();
|
|
333
|
+
json(res, 200, info);
|
|
334
|
+
} catch (e) {
|
|
335
|
+
json(res, 200, { hasUpdate: false, error: e.message });
|
|
336
|
+
}
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
328
340
|
if (req.method === 'POST' && path === '/api/stop') {
|
|
329
341
|
try {
|
|
330
342
|
const progress = readProgress();
|
|
@@ -604,6 +616,9 @@ const server = createServer((req, res) => {
|
|
|
604
616
|
});
|
|
605
617
|
});
|
|
606
618
|
|
|
619
|
+
// Start background update check
|
|
620
|
+
checkForUpdates();
|
|
621
|
+
|
|
607
622
|
server.listen(PORT, '127.0.0.1', () => {
|
|
608
623
|
console.log(`\n SEO Intel Dashboard Server`);
|
|
609
624
|
console.log(` http://localhost:${PORT}\n`);
|
package/setup/openclaw-bridge.js
CHANGED
|
@@ -258,7 +258,7 @@ export async function cliAgentSetup(systemCheck) {
|
|
|
258
258
|
|
|
259
259
|
const ask = (prompt) => new Promise(resolve => rl.question(prompt, resolve));
|
|
260
260
|
|
|
261
|
-
console.log('\n \x1b[36m\x1b[1m
|
|
261
|
+
console.log('\n \x1b[36m\x1b[1m🦀 SEO Intel — Agent-Powered Setup\x1b[0m\n');
|
|
262
262
|
console.log(' \x1b[2mOpenClaw is guiding your setup. Type your answers, or "done" to finish.\x1b[0m\n');
|
|
263
263
|
|
|
264
264
|
try {
|