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`.