merge: incorporate origin/main into community-mode branch

Conflicts resolved:
- VERSION: keep 0.14.0.0 (our branch > main's 0.13.1.0)
- CHANGELOG.md: keep both entries, 0.14.0.0 above 0.13.1.0

Main brought in v0.13.1.0 "Defense in Depth": auth token via file
instead of /health endpoint, Bearer auth on cookie picker data routes,
CORS tightened, state file expiry, textContent over innerHTML in
extension, symlink-aware path validation, portable freeze hook,
shell config input sanitization. 20 regression tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-28 07:38:15 -07:00
23 changed files with 488 additions and 66 deletions
+15 -3
View File
@@ -16,16 +16,28 @@ CONFIG_FILE="$STATE_DIR/config.yaml"
case "${1:-}" in
get)
KEY="${2:?Usage: gstack-config get <key>}"
grep -E "^${KEY}:" "$CONFIG_FILE" 2>/dev/null | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true
# Validate key (alphanumeric + underscore only)
if ! printf '%s' "$KEY" | grep -qE '^[a-zA-Z0-9_]+$'; then
echo "Error: key must contain only alphanumeric characters and underscores" >&2
exit 1
fi
grep -F "${KEY}:" "$CONFIG_FILE" 2>/dev/null | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true
;;
set)
KEY="${2:?Usage: gstack-config set <key> <value>}"
VALUE="${3:?Usage: gstack-config set <key> <value>}"
# Validate key (alphanumeric + underscore only)
if ! printf '%s' "$KEY" | grep -qE '^[a-zA-Z0-9_]+$'; then
echo "Error: key must contain only alphanumeric characters and underscores" >&2
exit 1
fi
mkdir -p "$STATE_DIR"
if grep -qE "^${KEY}:" "$CONFIG_FILE" 2>/dev/null; then
# Escape sed special chars in value and drop embedded newlines
ESC_VALUE="$(printf '%s' "$VALUE" | head -1 | sed 's/[&/\]/\\&/g')"
if grep -qF "${KEY}:" "$CONFIG_FILE" 2>/dev/null; then
# Portable in-place edit (BSD sed uses -i '', GNU sed uses -i without arg)
_tmpfile="$(mktemp "${CONFIG_FILE}.XXXXXX")"
sed "s/^${KEY}:.*/${KEY}: ${VALUE}/" "$CONFIG_FILE" > "$_tmpfile" && mv "$_tmpfile" "$CONFIG_FILE"
sed "s/^${KEY}:.*/${KEY}: ${ESC_VALUE}/" "$CONFIG_FILE" > "$_tmpfile" && mv "$_tmpfile" "$CONFIG_FILE"
else
echo "${KEY}: ${VALUE}" >> "$CONFIG_FILE"
fi
+2
View File
@@ -156,6 +156,8 @@ OUTCOME="$(json_safe "$OUTCOME")"
SESSION_ID="$(json_safe "$SESSION_ID")"
SOURCE="$(json_safe "$SOURCE")"
EVENT_TYPE="$(json_safe "$EVENT_TYPE")"
REPO_SLUG="$(json_safe "$REPO_SLUG")"
BRANCH="$(json_safe "$BRANCH")"
# Escape null fields — sanitize ERROR_CLASS and FAILED_STEP via json_safe()
ERR_FIELD="null"