mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-05 08:06:02 +00:00
* fix(analyze): prevent cache-hit native workers from aborting Delay parse worker startup until a cache miss requires it, fall back to sequential parsing when initial worker readiness fails, and preserve analyzer diagnostics/progress when heap respawn captures child output. Constraint: Node 25 and tree-sitter/N-API worker initialization can abort before ready, while warm-cache analysis should not start workers at all. Rejected: Treating status-134/SIGABRT as heap OOM unconditionally | native worker aborts require distinct recovery guidance and stderr/stdout evidence. Rejected: cli-progress noTTYOutput for respawn progress | it appends newline frames instead of preserving one-line redraw UX. Confidence: high Scope-risk: moderate Directive: Keep parse-worker creation behind confirmed cache misses and preserve TTY-style progress when respawn pipes stderr for crash classification. Tested: GitNexus impact analysis for ensureHeap, runChunkedParseAndResolve, createWorkerPool, WorkerPool, walkRepositoryPaths; GitNexus detect_changes scoped to staged worktree; targeted vitest for analyze respawn, parse lazy cache, filesystem walker, worker pool; npx tsc --noEmit; npm run build; NODE_OPTIONS='--max-old-space-size=8192' npm test. Not-tested: Windows terminal rendering and published npm package install path. * ci(docker): tolerate slower arm64 TypeScript builds Docker PR builds run gitnexus prepare under QEMU for linux/arm64, where the fixed 120s TypeScript timeout can kill otherwise healthy builds. Increase the default timeout and allow GITNEXUS_BUILD_TIMEOUT_MS to tune slower environments without changing the build steps. Constraint: PR #1751 Docker Build & Push gitnexus failed with spawnSync /bin/sh ETIMEDOUT while running node_modules/.bin/tsc in scripts/build.js.\nRejected: Rerunning CI only | the failure was the build script's deterministic timeout boundary under arm64 emulation, not a code assertion.\nConfidence: high\nScope-risk: narrow\nDirective: Keep build timeout changes in scripts/build.js configurable; do not hide real compiler failures, only allow slower successful compiles to finish.\nTested: GitNexus impact for gitnexus/scripts/build.js reported LOW; gitnexus detect_changes reported 1 changed file, 0 affected processes, low risk; git diff --check; gitnexus npm run build.\nNot-tested: GitHub Docker arm64 build rerun before pushing; local Docker multi-platform build under QEMU. * fix(analyze): truncate respawn progress safely Preserve complete ANSI escape sequences and grapheme boundaries when the respawn progress terminal shim truncates wrapped output, so the shim does not emit dangling escape bytes or split surrogate pairs while keeping raw writes untouched. Constraint: Claude review on PR #1751 flagged `s.slice(0, width)` in createAnsiPipeTerminal.write() as a latent terminal-corruption risk. Rejected: Adding a display-width dependency | a local helper is sufficient for this narrow respawn terminal shim and avoids new dependency churn. Rejected: Changing silent status-134 classification | current tests already document the output-less 134 fallback as heap guidance. Confidence: high Scope-risk: narrow Directive: Keep respawn terminal writes ANSI-aware and preserve rawWrite bypass semantics for callers that intentionally write control sequences. Tested: GitNexus impact for createAnsiPipeTerminal reported LOW; GitNexus detect_changes reported 2 changed files, 3 affected processes, medium risk; targeted vitest for analyze respawn progress and heap respawn; gitnexus npx tsc --noEmit; prettier check for changed files; eslint for changed files. Not-tested: Full npm test suite; manual terminal rendering on Windows. --------- Co-authored-by: wangxc <wangxc_a_bj@si-tech.com.cn>
113 lines
4.7 KiB
JavaScript
113 lines
4.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Build script that compiles gitnexus and inlines gitnexus-shared into the dist.
|
|
*
|
|
* Steps:
|
|
* 1. Build gitnexus-shared (tsc)
|
|
* 2. Build gitnexus (tsc)
|
|
* 3. Copy gitnexus-shared/dist → dist/_shared
|
|
* 4. Rewrite bare 'gitnexus-shared' specifiers → relative paths
|
|
*/
|
|
import { execSync } from 'node:child_process';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const ROOT = path.resolve(__dirname, '..');
|
|
const SHARED_ROOT = path.resolve(ROOT, '..', 'gitnexus-shared');
|
|
const DIST = path.join(ROOT, 'dist');
|
|
const SHARED_DEST = path.join(DIST, '_shared');
|
|
const DEFAULT_BUILD_TIMEOUT_MS = 300_000;
|
|
|
|
function getBuildTimeoutMs() {
|
|
const raw = process.env.GITNEXUS_BUILD_TIMEOUT_MS;
|
|
if (raw === undefined || raw.trim() === '') return DEFAULT_BUILD_TIMEOUT_MS;
|
|
|
|
const parsed = Number.parseInt(raw, 10);
|
|
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
|
|
console.warn(
|
|
`[build] ignoring invalid GITNEXUS_BUILD_TIMEOUT_MS=${JSON.stringify(raw)}; using ${DEFAULT_BUILD_TIMEOUT_MS}ms`,
|
|
);
|
|
return DEFAULT_BUILD_TIMEOUT_MS;
|
|
}
|
|
|
|
const BUILD_TIMEOUT_MS = getBuildTimeoutMs();
|
|
|
|
// ── 1. Build gitnexus-shared ───────────────────────────────────────
|
|
console.log('[build] compiling gitnexus-shared…');
|
|
const tscCmd =
|
|
process.platform === 'win32'
|
|
? path.join('node_modules', '.bin', 'tsc.cmd')
|
|
: path.join('node_modules', '.bin', 'tsc');
|
|
execSync(tscCmd, { cwd: SHARED_ROOT, stdio: 'inherit', timeout: BUILD_TIMEOUT_MS });
|
|
|
|
// ── 2. Build gitnexus ──────────────────────────────────────────────
|
|
console.log('[build] compiling gitnexus…');
|
|
execSync(tscCmd, { cwd: ROOT, stdio: 'inherit', timeout: BUILD_TIMEOUT_MS });
|
|
|
|
// ── 3. Copy shared dist ────────────────────────────────────────────
|
|
console.log('[build] copying shared module into dist/_shared…');
|
|
fs.cpSync(path.join(SHARED_ROOT, 'dist'), SHARED_DEST, { recursive: true });
|
|
|
|
// ── 4. Rewrite imports ─────────────────────────────────────────────
|
|
console.log('[build] rewriting gitnexus-shared imports…');
|
|
let rewritten = 0;
|
|
|
|
function rewriteFile(filePath) {
|
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
if (!content.includes('gitnexus-shared')) return;
|
|
|
|
const relDir = path.relative(path.dirname(filePath), SHARED_DEST);
|
|
// Always use posix separators and point to the package index
|
|
const relImport = relDir.split(path.sep).join('/') + '/index.js';
|
|
|
|
const updated = content
|
|
.replace(/from\s+['"]gitnexus-shared['"]/g, `from '${relImport}'`)
|
|
.replace(/import\(\s*['"]gitnexus-shared['"]\s*\)/g, `import('${relImport}')`);
|
|
|
|
if (updated !== content) {
|
|
fs.writeFileSync(filePath, updated);
|
|
rewritten++;
|
|
}
|
|
}
|
|
|
|
function walk(dir, extensions, cb) {
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const full = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
walk(full, extensions, cb);
|
|
} else if (extensions.some((ext) => entry.name.endsWith(ext))) {
|
|
cb(full);
|
|
}
|
|
}
|
|
}
|
|
|
|
walk(DIST, ['.js', '.d.ts'], rewriteFile);
|
|
|
|
// ── 5. Make CLI entry executable ────────────────────────────────────
|
|
const cliEntry = path.join(DIST, 'cli', 'index.js');
|
|
if (fs.existsSync(cliEntry)) fs.chmodSync(cliEntry, 0o755);
|
|
|
|
// ── 6. Build & copy web UI ──────────────────────────────────────────
|
|
const WEB_ROOT = path.resolve(ROOT, '..', 'gitnexus-web');
|
|
const WEB_DEST = path.join(DIST, '..', 'web');
|
|
|
|
if (fs.existsSync(path.join(WEB_ROOT, 'package.json'))) {
|
|
console.log('[build] building gitnexus-web…');
|
|
if (!fs.existsSync(path.join(WEB_ROOT, 'node_modules'))) {
|
|
console.log('[build] installing gitnexus-web dependencies…');
|
|
execSync('npm ci', { cwd: WEB_ROOT, stdio: 'inherit', timeout: BUILD_TIMEOUT_MS });
|
|
}
|
|
execSync('npm run build', { cwd: WEB_ROOT, stdio: 'inherit', timeout: BUILD_TIMEOUT_MS });
|
|
|
|
// Copy dist → gitnexus/web/ (shipped in the npm package)
|
|
fs.rmSync(WEB_DEST, { recursive: true, force: true });
|
|
fs.cpSync(path.join(WEB_ROOT, 'dist'), WEB_DEST, { recursive: true });
|
|
console.log('[build] copied web UI → gitnexus/web/');
|
|
} else {
|
|
console.log('[build] skipping web UI (gitnexus-web not found)');
|
|
}
|
|
|
|
console.log(`[build] done — rewrote ${rewritten} files.`);
|