chore: move build output under build/ and scripts into scripts/

Layout:
- scripts/ holds the four build scripts plus the new clean.sh
- cmake/ holds mingw64-toolchain.cmake
- the scripts default to build/linux, build/macos, build/windows, build/harness
- docs/ holds the audit documents, with the round 1 task list archived

Cleanup:
- scripts/clean.sh removes generated output, with --dry-run, --staging,
  --legacy and --all, and refuses tracked, protected or outside paths
- the Windows VST3 manifest now comes from cmake/moduleinfo.json.in, so its
  version, vendor and class IDs follow cmake/Plugin.cmake instead of a
  hand-written heredoc that could drift
- deleted the unused Source/GUI/Slider, which no code constructed
- fixed the hidden double processBlock overload: three warning lines to zero
- unslopped the build scripts, the two .cjs helpers and the CMake comments
- .gitignore covers the upstream JUCE Projucer and DemoRunner binaries

Verified: five scripts pass bash -n; the harness passes CTest with zero
warning lines; the Linux VST3 and Standalone link; the Windows cross-build
passes its x86-64, runtime-import and entry-point checks; each configure
exposes only its own targets; and a full build leaves Source/ and
third_party/JUCE unchanged. The generated manifest is identical to the
previous hand-written one.
This commit is contained in:
biggy committed 2026-10-06 09:06:53 +02:00
1 parent e4cea300db
commit facd5c5b5e
25 files changed
+438 -313

No files matched your search

+8 -8
View File
@@ -6,7 +6,7 @@ const { execFileSync } = require('child_process');
const dir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
const BAKED = "/usr/lib/node_modules/@nanonets/graft/dist/claude";
// The dist/claude dir of @nanonets/graft resolved from a base whose node_modules is searched.
// dist/claude inside @nanonets/graft, resolved from a directory npm searches.
function fromPkg(base) {
try {
const pkg = require.resolve('@nanonets/graft/package.json', { paths: [base] });
@@ -14,7 +14,7 @@ function fromPkg(base) {
} catch { return null; }
}
// The global node_modules dir per npm (handles Homebrew/Windows/volta). Queried on demand.
// The global node_modules directory, as npm reports it. Queried only when needed.
function globalRoot() {
try {
const root = execFileSync('npm', ['root', '-g'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], shell: process.platform === 'win32' }).trim();
@@ -22,14 +22,14 @@ function globalRoot() {
} catch { return null; /* npm unavailable */ }
}
// The version of the package a dist/claude dir belongs to, or null if unreadable.
// The version of the package that owns a dist/claude directory, or null.
function versionOf(distClaude) {
try {
return JSON.parse(fs.readFileSync(path.join(distClaude, '..', '..', 'package.json'), 'utf8')).version || null;
} catch { return null; }
}
// Numeric-dotted compare of the release part; an unreadable version loses to any known one.
// Compares dotted version numbers. An unreadable version counts as older.
function newer(a, b) {
if (!a) return false;
if (!b) return true;
@@ -42,7 +42,7 @@ function newer(a, b) {
return false;
}
// The highest-versioned dir in `dirs` that actually contains `name`, or null.
// The highest-versioned entry in `dirs` that contains `name`, or null.
function best(dirs, name) {
let bestDir = null, bestVer = null;
for (const d of dirs) {
@@ -54,14 +54,14 @@ function best(dirs, name) {
}
function entry(name) {
// Cheap candidates first, and only shell out to npm when every one of them misses.
// Check the cheap candidates first, and run npm only if none of them match.
const cheap = [BAKED, fromPkg(dir), fromPkg(path.join(path.dirname(process.execPath), '..', 'lib'))];
const hit = best(cheap, name);
if (hit) return path.join(hit, name);
const gr = globalRoot();
const global = gr && path.join(gr, '@nanonets', 'graft', 'dist', 'claude');
if (global && fs.existsSync(path.join(global, name))) return path.join(global, name);
return path.join(dir, 'dist', 'claude', name); // last-ditch; import will no-op if absent
return path.join(dir, 'dist', 'claude', name); // fallback; the import does nothing when the file is absent
}
import(pathToFileURL(entry("hooks.js")).href).then((m) => m.main(process.argv[2])).catch(() => { /* graft unavailable, no-op */ });
import(pathToFileURL(entry("hooks.js")).href).then((m) => m.main(process.argv[2])).catch(() => { /* graft is unavailable: do nothing */ });