First step of the dashboard-tab consolidation (#1464): a static menu page linking to every top-level surface, so the tab strip can later shed its `→` page-links and the dashboard can graduate Stats/Settings to their own pages. - dashboard/src/home.{html,css,js}: a responsive grid of link tiles (D4SHB04RD, FL0W, L0GS, M4TR1X). Pure portal — no tabbar/SSE. Colours from the shared theme.css, base typography from common.css. The Matrix tile is hidden until home.js confirms `matrix_gui_enabled` (same gating as the dashboard's M4TR1X tab); home.js also fills the swarm/hive identity line. - build.mjs: emit home.{html,css,js}. Served at `/home.html` for now (additive — reachable via the existing ServeDir, links to surfaces at their current routes). Promoting it to `/` (and relocating the dashboard to `/dashboard` + wiring `← home` back-links) is the next step — a route swap that touches hive-c0re's static router, coordinating with damocles. Deliberately decoupled so this page ships standalone without conflicting with the in-flight tabs.js change (#1449/#1451). Part of #1464.
98 lines
4.3 KiB
JavaScript
98 lines
4.3 KiB
JavaScript
// esbuild build for @hive/dashboard. Output layout (`dist/`):
|
|
//
|
|
// dist/index.html served by the Rust router at GET /
|
|
// dist/flow.html served at GET /flow.html
|
|
// dist/logs.html served at GET /logs.html
|
|
// dist/static/tabs.js /index.html entry — tab renderers +
|
|
// tab routing + refreshState
|
|
// dist/static/flow.js /flow.html entry — broker terminal +
|
|
// operator inbox + @-mention composer
|
|
// dist/static/logs.js /logs.html entry — build/agent/system
|
|
// log viewer sub-tabs
|
|
// dist/static/{tabs,flow,logs}.js.map source map siblings
|
|
// dist/static/common.css loaded by every page (@hive/shared
|
|
// imports + shared typography/badges/
|
|
// buttons/inbox/side-panel)
|
|
// dist/static/dashboard.css /index.html only (dashboard-specific)
|
|
// dist/static/flow.css /flow.html only (flow chrome + composer)
|
|
// dist/static/logs.css /logs.html only (log viewer sub-tabs)
|
|
//
|
|
// All three JS entries bundle `./common.js` (DOM helpers, Panel singleton,
|
|
// NOTIF, path linkification) independently — esbuild inlines the shared
|
|
// module into each bundle rather than emitting a shared chunk (no
|
|
// `splitting: true`). The Rust binary mounts `dist/` as a
|
|
// `tower_http::ServeDir` fallback; the layout above keeps every URL
|
|
// the HTML files reference reachable without rewriting paths in the
|
|
// HTML.
|
|
|
|
import { build } from 'esbuild';
|
|
import { mkdirSync, copyFileSync, rmSync } from 'node:fs';
|
|
import { dirname, resolve } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const src = (p) => resolve(here, 'src', p);
|
|
const dist = (p) => resolve(here, 'dist', p);
|
|
const staticDir = (p) => resolve(here, 'dist', 'static', p);
|
|
|
|
rmSync(dist(''), { recursive: true, force: true });
|
|
mkdirSync(staticDir(''), { recursive: true });
|
|
|
|
// Bundle all three JS entries. ES-module output, browser target, no minify
|
|
// (line-aligned source aids debugging; minification belongs in a later
|
|
// follow-up once asset sizes warrant it). esbuild writes each entry
|
|
// to `static/<name>.js` based on the entryPoint basename.
|
|
await build({
|
|
entryPoints: [src('tabs.js'), src('flow.js'), src('logs.js'), src('home.js')],
|
|
outdir: staticDir(''),
|
|
bundle: true,
|
|
format: 'esm',
|
|
platform: 'browser',
|
|
target: ['es2022'],
|
|
sourcemap: true,
|
|
logLevel: 'info',
|
|
});
|
|
|
|
// Stream-worker entry (#448). Lives in a separate bundle: SharedWorker
|
|
// scripts run in a different global (`self` is the worker scope, no
|
|
// `window`) so they can't be inlined into tabs.js / flow.js. Output is
|
|
// at `static/stream-worker.js`; common.js's `openStream` references
|
|
// `/static/stream-worker.js` as the SharedWorker URL. `format: 'iife'`
|
|
// matches the classic-script load (`new SharedWorker(url, name)` with
|
|
// no `{ type: 'module' }`); Firefox is the #448 target and module
|
|
// SharedWorker support there is patchy, so keeping the worker as a
|
|
// classic script + IIFE bundle is the compatible default. argus nit
|
|
// on #453: if a future contributor adds an `import` to this bundle,
|
|
// the IIFE format will surface it as a build error rather than
|
|
// silently shipping broken code.
|
|
await build({
|
|
entryPoints: [src('stream-worker.js')],
|
|
outdir: staticDir(''),
|
|
bundle: true,
|
|
format: 'iife',
|
|
platform: 'browser',
|
|
target: ['es2022'],
|
|
sourcemap: true,
|
|
logLevel: 'info',
|
|
});
|
|
|
|
// Bundle CSS — one entry per page. esbuild resolves @import including
|
|
// the package re-exports from @hive/shared. Each page loads theme.css
|
|
// (the standalone Catppuccin palette — kept its own file so a theme
|
|
// swap replaces only it) + common.css (shared typography, badges,
|
|
// buttons, inbox, side panel) plus its own page-specific bundle.
|
|
for (const entry of ['theme.css', 'common.css', 'dashboard.css', 'flow.css', 'logs.css', 'home.css']) {
|
|
await build({
|
|
entryPoints: [src(entry)],
|
|
outfile: staticDir(entry),
|
|
bundle: true,
|
|
loader: { '.css': 'css' },
|
|
logLevel: 'info',
|
|
});
|
|
}
|
|
|
|
for (const html of ['index.html', 'flow.html', 'logs.html', 'home.html']) {
|
|
copyFileSync(src(html), dist(html));
|
|
}
|
|
|
|
console.log('dashboard build ok →', dist(''));
|