- Rename native Rust crates: gsd-engine → forge-engine, gsd-ast → forge-ast, gsd-grep → forge-grep - Update all crate dependencies (Cargo.toml, .rs source) and N-API artifacts - Mass rename log prefix [gsd] → [forge] across 81 files (scripts, src/, extensions, tests) - Rename log prefix "gsd-db:" → "forge-db:" in template literals - Update nix flake: add sf-run-native devShell with Rust toolchain for native addon builds - Update CI workflow artifact names (build-native.yml) - Verify only packages/native/* touched (no upstream pi-* packages renamed) Rationale: Complete gsd-2 → singularity-forge rebrand (2026-04-15). Native addon is sf-run-specific; all gsd-prefixed logging and crate names must align with new identity. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
110 lines
3.1 KiB
JavaScript
110 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Rebuild the Next.js web host only when web source files are newer than the
|
|
* staged standalone build. Skips the build when nothing has changed.
|
|
*
|
|
* Also self-heals a missing/incomplete web dependency install so `npm run gsd:web`
|
|
* doesn't fail with bare `next` command-not-found errors.
|
|
*
|
|
* Exit codes:
|
|
* 0 — build was up-to-date or successfully rebuilt
|
|
* 1 — build failed
|
|
*/
|
|
|
|
'use strict'
|
|
|
|
const { execSync } = require('node:child_process')
|
|
const { existsSync, readdirSync, statSync } = require('node:fs')
|
|
const { join, resolve } = require('node:path')
|
|
|
|
// Skip on Windows — Next.js webpack build hits EPERM scanning system dirs
|
|
if (process.platform === 'win32') {
|
|
console.log('[forge] Web build skipped on Windows.')
|
|
process.exit(0)
|
|
}
|
|
|
|
const root = resolve(__dirname, '..')
|
|
const webRoot = join(root, 'web')
|
|
// Also watch src/ because api routes import directly from src/web/* and src/resources/*
|
|
const srcRoot = join(root, 'src')
|
|
const stagedSentinel = join(root, 'dist', 'web', 'standalone', 'server.js')
|
|
|
|
// Directories inside web/ that are not source and should be ignored for
|
|
// staleness comparison.
|
|
const IGNORED_DIRS = new Set(['node_modules', '.next', '.turbo', 'dist', 'out', '.cache'])
|
|
|
|
/**
|
|
* Walk a directory tree, yield the mtime of every file, skipping ignored dirs.
|
|
* Returns the maximum mtime found (ms since epoch), or 0 if nothing found.
|
|
*/
|
|
function newestMtime(dir) {
|
|
let max = 0
|
|
let stack = [dir]
|
|
while (stack.length > 0) {
|
|
const current = stack.pop()
|
|
let entries
|
|
try {
|
|
entries = readdirSync(current, { withFileTypes: true })
|
|
} catch {
|
|
continue
|
|
}
|
|
for (const entry of entries) {
|
|
if (entry.isDirectory()) {
|
|
if (!IGNORED_DIRS.has(entry.name)) {
|
|
stack.push(join(current, entry.name))
|
|
}
|
|
continue
|
|
}
|
|
try {
|
|
const mt = statSync(join(current, entry.name)).mtimeMs
|
|
if (mt > max) max = mt
|
|
} catch {
|
|
// skip unreadable files
|
|
}
|
|
}
|
|
}
|
|
return max
|
|
}
|
|
|
|
function sentinelMtime() {
|
|
try {
|
|
return statSync(stagedSentinel).mtimeMs
|
|
} catch {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
function hasWebBuildDependencies() {
|
|
return existsSync(join(webRoot, 'node_modules', '.bin', 'next'))
|
|
}
|
|
|
|
function ensureWebBuildDependencies() {
|
|
if (hasWebBuildDependencies()) {
|
|
return
|
|
}
|
|
|
|
console.log('[forge] Web build dependencies are missing or incomplete — running npm --prefix web ci...')
|
|
execSync('npm --prefix web ci', { cwd: root, stdio: 'inherit' })
|
|
}
|
|
|
|
const sourceMtime = Math.max(newestMtime(webRoot), newestMtime(srcRoot))
|
|
const builtMtime = sentinelMtime()
|
|
|
|
if (builtMtime > 0 && builtMtime >= sourceMtime) {
|
|
console.log('[forge] Web build is up-to-date, skipping rebuild.')
|
|
process.exit(0)
|
|
}
|
|
|
|
if (builtMtime === 0) {
|
|
console.log('[forge] No staged web build found — building now...')
|
|
} else {
|
|
console.log('[forge] Web/src source has changed since last build — rebuilding...')
|
|
}
|
|
|
|
try {
|
|
ensureWebBuildDependencies()
|
|
execSync('npm run build:web-host', { cwd: root, stdio: 'inherit' })
|
|
} catch (err) {
|
|
console.error('[forge] Web build failed:', err.message)
|
|
process.exit(1)
|
|
}
|