singularity-forge/scripts
Jeremy McSpadden 867a4be297 fix(memory): fix memory and resource leaks across TUI, LSP, DB, and automation (#2314)
* fix(memory): fix memory and resource leaks across TUI, LSP, DB, and automation

Addresses all findings from a systematic memory leak audit across five
dimensions: event listeners, timers, file system handles, subscriptions/
closures, and GSD automation lifecycle.

Critical fixes:

rpc-client.ts: stderr .on("data") handler attached in start() was never
removed in stop(). Now stored as _stderrHandler and removed via
removeListener() on stop.

lsp/client.ts: Three process.on() handlers (beforeExit, SIGINT, SIGTERM)
registered at module load time with anonymous functions — impossible to
remove. Now stored as named references; new removeProcessHandlers() export
allows graceful teardown. stdout/stderr stream listeners in
startMessageReader/startStderrReader also stored per-client in
clientStreamHandlers map and removed in shutdownClient() and shutdownAll().

parallel-orchestrator.ts: spawnWorker() attached 5 listeners to child
process streams on every spawn with no removal on worker stop/respawn,
accumulating listeners indefinitely. Added cleanup() field to WorkerInfo;
called via removeAllListeners() on exit, graceful stop, stale detection,
and dead PID cleanup paths. Also: module-level state.workers Map was never
cleared between orchestration runs; startParallel() and resetOrchestrator()
now iterate and clean up all WorkerInfo entries before reassigning state.

scripts/watch-resources.js: fs.watch() return value was discarded (OS
watcher never closed) and the fallback setInterval handle was also
discarded (timer ran forever). Both now stored; process.on("exit") handler
closes/clears them.

gsd-db.ts: closeDatabase() did not checkpoint the WAL before closing —
.db-shm/.db-wal files accumulated on disk across crash-recovery cycles.
Now runs PRAGMA wal_checkpoint(TRUNCATE) before close. Also added a
one-time process.on("exit") handler in openDatabase() so the handle is
always closed even on unclean exits.

Medium fixes:

bg-shell/overlay.ts: 1-second refresh setInterval only cleared in
keyboard exit handler; abnormal teardown leaked the timer. Added dispose()
method that unconditionally clears it.

file-watcher.ts: pending debounce Map was scoped inside startFileWatcher()
making it inaccessible to stopFileWatcher(). Moved to module scope;
stopFileWatcher() now clears all pending timers and empties the map before
closing the watcher.

auto-supervisor.ts: registerSigtermHandler() could accumulate multiple
SIGTERM handlers if called without passing back the previous reference.
Added module-level _currentSigtermHandler; old handler is always removed
before registering the new one regardless of whether caller passes it.

Low-severity fixes:

print-mode.ts: session.subscribe() return value was discarded. Now stored
and called in a finally block to guarantee cleanup on both normal
completion and errors.

rpc-mode.ts: same — subscribe() unsubscribe now called in the shutdown
path before process.exit().

theme.ts: onThemeChangeCallback singleton silently overwrote any previous
subscriber. Converted to Set<() => void>; onThemeChange() now returns a
cleanup function. All four internal call sites updated to forEach().
Backward-compatible — existing callers that discard the return are unaffected.

* fix: ensure unsubscribe is called on error/abort in print-mode

The PR #2314 added unsubscribe storage but still called process.exit(1)
directly, bypassing the unsubscribe. Wrapped in try/finally to guarantee
cleanup runs before exit.
2026-03-24 07:23:36 -06:00
..
build-web-if-stale.cjs fix: skip web build on Windows — Next.js webpack hits EPERM on system dirs 2026-03-21 13:30:23 -06:00
bump-version.mjs feat(ci): automate prod-release with version bump, changelog, and tag push (#1194) 2026-03-18 11:17:43 -06:00
check-skill-references.mjs fix: remove broken SwiftUI skill and add CI reference check (#1476) (#1520) 2026-03-19 18:04:37 -06:00
ci_monitor.cjs feat: add GitHub Workflows skill with CI workflow and ci_monitor tool (#294) 2026-03-13 22:31:17 -06:00
ci_monitor.md feat: add GitHub Workflows skill with CI workflow and ci_monitor tool (#294) 2026-03-13 22:31:17 -06:00
copy-export-html.cjs refactor: extract inline build scripts from package.json to files 2026-03-16 13:34:05 -05:00
copy-resources.cjs fix: apply pi manifest opt-out to extension-discovery.ts (#1545) 2026-03-20 08:11:51 -06:00
copy-themes.cjs refactor: extract inline build scripts from package.json to files 2026-03-16 13:34:05 -05:00
dev-cli.js feat(web): browser-based web interface (#1717) 2026-03-21 12:16:54 -06:00
dev.js refactor: deduplicate help text, cross-platform validate-pack, fix dev.js 2026-03-16 13:29:31 -05:00
docs-prompt-injection-scan.sh feat(ci): skip build/test for docs-only PRs and add prompt injection scan (#1699) 2026-03-21 08:39:03 -06:00
ensure-workspace-builds.cjs fix: prevent getLoadedSkills crash and auto-build workspace packages (#1767) 2026-03-21 09:19:48 -06:00
generate-changelog.mjs feat(ci): automate prod-release with version bump, changelog, and tag push (#1194) 2026-03-18 11:17:43 -06:00
install-hooks.sh feat: add pre-commit secret scanner and CI secret detection (#1148) 2026-03-18 08:33:17 -06:00
install-pi-global.js Add pi global install scripts (#57) 2026-03-11 14:34:03 -06:00
link-workspace-packages.cjs fix: detect broken install and add Windows symlink fallback (#890) 2026-03-17 09:35:57 -06:00
postinstall.js fix: strip clack UI from postinstall, keep silent Playwright download (#783) 2026-03-16 21:35:04 -06:00
pr-risk-check.mjs feat(ci): PR risk checker — classify changed files by system and surface risk level (#1930) 2026-03-21 18:12:01 -06:00
preview-dashboard.ts feat(dashboard): two-column layout with redesigned widget (#1530) 2026-03-19 20:07:18 -06:00
recover-gsd-1364.ps1 fix: recover + prevent #1364 .gsd/ data-loss (v2.30.0–v2.38.0) (#1635) 2026-03-20 13:26:09 -06:00
recover-gsd-1364.sh fix: recover + prevent #1364 .gsd/ data-loss (v2.30.0–v2.38.0) (#1635) 2026-03-20 13:26:09 -06:00
recover-gsd-1668.ps1 fix(worktree): detect default branch instead of hardcoding "main" on milestone merge (#1668) (#1669) 2026-03-21 08:34:55 -06:00
recover-gsd-1668.sh fix(worktree): detect default branch instead of hardcoding "main" on milestone merge (#1668) (#1669) 2026-03-21 08:34:55 -06:00
secret-scan.sh feat: add pre-commit secret scanner and CI secret detection (#1148) 2026-03-18 08:33:17 -06:00
stage-web-standalone.cjs feat(web): browser-based web interface (#1717) 2026-03-21 12:16:54 -06:00
sync-pkg-version.cjs feat: vendor Pi source into workspace monorepo 2026-03-12 21:55:17 -06:00
uninstall-pi-global.js Add pi global install scripts (#57) 2026-03-11 14:34:03 -06:00
update-changelog.mjs feat(ci): automate prod-release with version bump, changelog, and tag push (#1194) 2026-03-18 11:17:43 -06:00
validate-pack.js feat(web): browser-based web interface (#1717) 2026-03-21 12:16:54 -06:00
validate-pack.sh fix: broken npm install — remove bundleDependencies, use postinstall symlinks (#369) 2026-03-14 10:04:12 -06:00
verify-s03.sh feat(wizard): add BRAVE_ANSWERS_KEY support 2026-03-10 22:44:28 -06:00
verify-s04.sh Replace remaining 'get stuff done' instances in verify script 2026-03-11 08:11:11 -06:00
version-stamp.mjs feat(ci): implement three-stage promotion pipeline (Dev → Test → Prod) (#1098) 2026-03-18 00:40:06 -06:00
watch-resources.js fix(memory): fix memory and resource leaks across TUI, LSP, DB, and automation (#2314) 2026-03-24 07:23:36 -06:00