bun was the wrong runtime for our environment, two ways:
1. bun doesn't ship node:sqlite. sf-db.ts falls back through node:sqlite
→ better-sqlite3 → null. Result: 'No SQLite provider available' and
degraded-mode filesystem-state derivation, even though sqlite is
actually available (node:sqlite under node, bun:sqlite under bun —
both valid, but our code only knows the node names).
2. bun's loader doesn't inherit the system library search path under
Nix. libz.so.1 isn't found for forge_engine.node, so the native
addon falls through to JS implementations (slower).
Both warnings ("Native addon not available", "DB unavailable —
degraded mode") were the symptom of "we're running under bun".
Fix: use node + the existing src/resources/extensions/sf/tests/
resolve-ts.mjs loader hook (which already handles .js → .ts
import-specifier remapping for runtime resolution) +
--experimental-strip-types (node 22+, native in 24).
Result: from-source via node loads cleanly. No native warning.
No sqlite warning. No degraded mode. Exec: `./bin/sf-from-source
--print "..."` returns the model output and nothing else.
Drops the LD_LIBRARY_PATH zlib-injection hack that was added in
4912f6ea8 — that was working around the bun native-loader issue
that doesn't exist under node.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bun's loader doesn't inherit the same library search path as node under
Nix, so require('forge_engine.linux-x64.node') fails with
'libz.so.1: cannot open shared object file' even when the native addon
exists at the expected path. Result: sf-from-source ran in
JS-fallback mode, and we'd been working around it by switching to
node dist/loader.js — which forces a manual `npm run copy-resources`
after every src/ change to keep dist in sync.
This wraps sf-from-source to find a Nix-store zlib at startup and
prepend it to LD_LIBRARY_PATH before exec'ing bun. The native addon
loads cleanly; from-source becomes the reliable default again; no
more dist drift to worry about.
Find pattern: /nix/store/*-zlib-*/lib/libz.so.1 at maxdepth 4
(maxdepth 2 was too shallow — the hash dir is depth 1, lib is depth 2,
the .so.1 file is depth 3, plus we want the parent dir for
LD_LIBRARY_PATH so '%h' on a depth-3 match gives the lib dir).
Outside Nix (no /nix/store), this is a no-op and falls through to
the existing exec.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updates channel prefixes, log messages, comments, and configuration values
across daemon, mcp-server, and related packages to complete the rebrand from
gsd to sf-run naming.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When gsd-from-source is invoked via a symlink (e.g. ~/.bun/bin/gsd-real
pointing at it so `gsd` resolves to source without further indirection),
BASH_SOURCE[0] is the symlink path, not the real file. The previous
dirname-of-BASH_SOURCE[0] approach resolved SCRIPT_DIR to the symlink's
parent dir (e.g. ~/.bun/bin) and tried to bun-run ~/.bun/src/loader.ts,
which doesn't exist.
Wrapping BASH_SOURCE[0] in readlink -f resolves the physical path first,
so SCRIPT_DIR always points at bin/ inside the gsd source checkout
regardless of how the script is reached.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds bin/gsd-from-source shell wrapper that bun-runs src/loader.ts, so
local commits are live without reinstalling gsd-pi. Patches loader.ts
to respect a pre-set GSD_BIN_PATH (previously it clobbered the env var
with process.argv[1], forcing subagent spawns to point at the .ts
loader path which child_process.spawn can't execute).
Why: working on fixes like #4251 required full `bun install -g --trust
gsd-pi` cycles plus longcat shim re-patching for every iteration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>