diff --git a/.gitignore b/.gitignore index faeb8b4..680461b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,6 @@ dist/ # Dependencies vendor/ frontend/node_modules/ -frontend/src/js/lib/ -frontend/src/css/lib/ # IDE .idea/ diff --git a/frontend/embed.go b/frontend/embed.go index 15591e2..e4d3898 100644 --- a/frontend/embed.go +++ b/frontend/embed.go @@ -3,7 +3,11 @@ package frontend import "embed" -// Assets contains the built frontend files from the dist directory. +// Assets contains the frontend files served by the Wails asset server. +// We embed the root index.html and the entire src/ tree (stylesheets, +// scripts, vendor libs and static assets) so that `go build` works +// without a separate npm build step. // -//go:embed all:dist +//go:embed index.html +//go:embed all:src var Assets embed.FS diff --git a/frontend/index.html b/frontend/index.html index 266b0bc..074d29e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -5,6 +5,9 @@ Nexus Terminal + + + diff --git a/frontend/scripts/build.js b/frontend/scripts/build.js index 6eef7ab..5911418 100644 --- a/frontend/scripts/build.js +++ b/frontend/scripts/build.js @@ -1,13 +1,14 @@ /** * build.js — Build script for the Nexus Terminal frontend. * - * In production mode (no flags): copies assets and validates that all - * required files are in place. + * In production mode (no flags): copies vendor assets, assembles the + * dist/ directory with all files needed by the Wails embed, and validates + * that every required file is present. * - * In watch mode (--watch): copies assets, then watches for source changes - * and prints a notification when files change. Wails dev mode handles the - * actual live-reload; this script simply keeps the process alive so the - * frontend:dev:watcher contract is satisfied. + * In watch mode (--watch): performs the same build, then watches for + * source changes and prints a notification when files change. Wails dev + * mode handles the actual live-reload; this script simply keeps the + * process alive so the frontend:dev:watcher contract is satisfied. */ 'use strict'; @@ -16,29 +17,86 @@ const path = require('path'); const { execSync } = require('child_process'); const frontendDir = path.resolve(__dirname, '..'); +const distDir = path.join(frontendDir, 'dist'); const watchMode = process.argv.includes('--watch'); -// Files that must exist after a successful build +// Files that must exist after a successful build (relative to frontend/) const requiredFiles = [ 'dist/index.html', - 'src/css/lib/xterm.css', - 'src/js/lib/xterm.min.js', - 'src/js/lib/xterm-addon-fit.min.js', - 'src/js/lib/xterm-addon-search.min.js', - 'src/js/lib/xterm-addon-web-links.min.js', + 'dist/src/css/lib/xterm.css', + 'dist/src/js/lib/xterm.min.js', + 'dist/src/js/lib/xterm-addon-fit.min.js', + 'dist/src/js/lib/xterm-addon-search.min.js', + 'dist/src/js/lib/xterm-addon-web-links.min.js', ]; /** - * Runs the asset copy script to ensure library files are present. + * Recursively copies a directory tree, creating parents as needed. + */ +function copyDirSync(src, dest) { + fs.mkdirSync(dest, { recursive: true }); + for (const entry of fs.readdirSync(src, { withFileTypes: true })) { + const srcPath = path.join(src, entry.name); + const destPath = path.join(dest, entry.name); + if (entry.isDirectory()) { + copyDirSync(srcPath, destPath); + } else { + fs.copyFileSync(srcPath, destPath); + } + } +} + +/** + * Removes a directory tree if it exists. + */ +function cleanDir(dir) { + if (fs.existsSync(dir)) { + fs.rmSync(dir, { recursive: true, force: true }); + } +} + +/** + * Runs the asset copy script to pull xterm files into src/js/lib/ and + * src/css/lib/. */ function copyAssets() { - console.log('[build] Copying library assets…'); + console.log('[build] Copying vendor library assets…'); execSync('node scripts/copy-assets.js', { cwd: frontendDir, stdio: 'inherit', }); } +/** + * Assembles the dist/ directory with everything the Wails embed needs: + * dist/index.html + * dist/src/css/ (application + lib stylesheets) + * dist/src/js/ (application + lib scripts) + * dist/src/components/ (if present) + * dist/src/assets/ (if present) + */ +function buildDist() { + console.log('[build] Assembling dist/ directory…'); + + // Start fresh so stale files are removed + cleanDir(distDir); + fs.mkdirSync(distDir, { recursive: true }); + + // Copy the root index.html + fs.copyFileSync( + path.join(frontendDir, 'index.html'), + path.join(distDir, 'index.html'), + ); + + // Copy the entire src/ tree (CSS, JS, components, assets, lib files) + const srcDir = path.join(frontendDir, 'src'); + if (fs.existsSync(srcDir)) { + copyDirSync(srcDir, path.join(distDir, 'src')); + } + + console.log('[build] dist/ assembled.'); +} + /** * Validates that every required file exists. * Returns true if all files are present. @@ -67,7 +125,7 @@ function watch() { console.log(`[build] Watching ${srcDir} for changes…`); // Use fs.watch recursively where supported (macOS, Windows). - // On Linux, this falls back to non-recursive — acceptable for dev use. + // On Linux this falls back to non-recursive — acceptable for dev use. try { fs.watch(srcDir, { recursive: true }, (_event, filename) => { if (filename) { @@ -77,7 +135,6 @@ function watch() { }); } catch (err) { console.warn('[build] Recursive watch not supported; polling fallback.'); - // Keep the process alive even if watch fails } // Prevent the process from exiting @@ -93,6 +150,8 @@ try { process.exit(1); } +buildDist(); + if (!validate()) { console.error('[build] Validation failed — some required files are missing.'); process.exit(1); diff --git a/frontend/src/css/lib/xterm.css b/frontend/src/css/lib/xterm.css new file mode 100644 index 0000000..7bed72e --- /dev/null +++ b/frontend/src/css/lib/xterm.css @@ -0,0 +1 @@ +/* Placeholder — replaced with the real xterm.css after `npm install`. */ diff --git a/frontend/src/js/lib/xterm-addon-fit.min.js b/frontend/src/js/lib/xterm-addon-fit.min.js new file mode 100644 index 0000000..eacc7ae --- /dev/null +++ b/frontend/src/js/lib/xterm-addon-fit.min.js @@ -0,0 +1 @@ +// Placeholder — replaced with the real xterm-addon-fit library after `npm install`. diff --git a/frontend/src/js/lib/xterm-addon-search.min.js b/frontend/src/js/lib/xterm-addon-search.min.js new file mode 100644 index 0000000..c7a999d --- /dev/null +++ b/frontend/src/js/lib/xterm-addon-search.min.js @@ -0,0 +1 @@ +// Placeholder — replaced with the real xterm-addon-search library after `npm install`. diff --git a/frontend/src/js/lib/xterm-addon-web-links.min.js b/frontend/src/js/lib/xterm-addon-web-links.min.js new file mode 100644 index 0000000..2ad3e6b --- /dev/null +++ b/frontend/src/js/lib/xterm-addon-web-links.min.js @@ -0,0 +1 @@ +// Placeholder — replaced with the real xterm-addon-web-links library after `npm install`. diff --git a/frontend/src/js/lib/xterm.min.js b/frontend/src/js/lib/xterm.min.js new file mode 100644 index 0000000..5b46210 --- /dev/null +++ b/frontend/src/js/lib/xterm.min.js @@ -0,0 +1 @@ +// Placeholder — replaced with the real xterm library after `npm install`.