fix(bins): cygpath-normalize SCRIPT_DIR for bun imports; surface learnings-log errors (#1950)

Under Windows git-bash, pwd yields a POSIX path (/c/Users/...) that Bun on
Windows cannot resolve as an ES module specifier. gstack-learnings-log
interpolates SCRIPT_DIR into a bun -e import, so every invocation died with
"Cannot find module" — and 2>/dev/null swallowed the error, silently
dropping every AI-logged learning for Windows users.

- 3-line cygpath -m guard in gstack-learnings-log and gstack-question-log
  (which gains the same import shape in the next commit). Matches the
  duplicated IS_WINDOWS convention in setup; no shared shell lib exists.
- learnings-log adopts question-log's set +e / TMPERR capture pattern
  wholesale: validation errors now print to stderr. The old
  `if [ $? -ne 0 ]` check was dead code under set -euo pipefail — the
  script exited at the failing assignment before reaching it.
- New test/bin-windows-bun-import-paths.test.ts: static invariant (any
  bash bin interpolating $SCRIPT_DIR into a bun -e import must carry the
  guard) + behavioral end-to-end run invoked via `bash <bin>` — added to
  the windows-free-tests workflow list so the conversion is proven on the
  only platform where the bug exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-06-11 20:29:19 -07:00
co-authored by Claude Fable 5
parent da06ef1504
commit c21249cbdd
4 changed files with 145 additions and 3 deletions
+19 -3
View File
@@ -7,13 +7,24 @@
# by gstack-learnings-search ("latest winner" per key+type).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Windows git-bash (#1950): pwd yields a POSIX path (/c/Users/...), which Bun
# on Windows cannot resolve as an ES module specifier in the import below.
# cygpath -m converts to C:/Users/... which Bun accepts.
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*) command -v cygpath >/dev/null 2>&1 && SCRIPT_DIR="$(cygpath -m "$SCRIPT_DIR")" ;;
esac
eval "$("$SCRIPT_DIR/gstack-slug" 2>/dev/null)"
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
mkdir -p "$GSTACK_HOME/projects/$SLUG"
INPUT="$1"
# Validate and sanitize input
# Validate and sanitize input. Errors surface (#1950): stderr is captured and
# printed on failure instead of swallowed — a silent exit 1 here cost Windows
# users every AI-logged learning.
TMPERR=$(mktemp)
trap 'rm -f "$TMPERR"' EXIT
set +e
VALIDATED=$(printf '%s' "$INPUT" | bun -e "
import { hasInjection } from '$SCRIPT_DIR/../lib/jsonl-store.ts';
const raw = await Bun.stdin.text();
@@ -63,9 +74,14 @@ if (!j.ts) j.ts = new Date().toISOString();
j.trusted = j.source === 'user-stated';
console.log(JSON.stringify(j));
" 2>/dev/null)
" 2>"$TMPERR")
VALIDATE_RC=$?
set -e
if [ $? -ne 0 ] || [ -z "$VALIDATED" ]; then
if [ $VALIDATE_RC -ne 0 ] || [ -z "$VALIDATED" ]; then
if [ -s "$TMPERR" ]; then
cat "$TMPERR" >&2
fi
exit 1
fi