diff --git a/clients/scripts/check-flexframe.sh b/clients/scripts/check-flexframe.sh index 159a12d0e28..da3b2f9f7c6 100755 --- a/clients/scripts/check-flexframe.sh +++ b/clients/scripts/check-flexframe.sh @@ -70,7 +70,16 @@ fi # (lines whose first non-whitespace is `//` or `///`). AGENTS.md-style # warnings like `// ⚠️ No .frame(maxWidth:) in LazyVStack cells` would # otherwise false-positive. -RAW_HITS=$(rg -n --no-heading "$PATTERN" "${SCAN_DIRS[@]}" 2>/dev/null \ +# +# `-U --multiline-dotall` enables multiline matching so `.frame(` wrapped +# across lines (opening paren on one line, `maxWidth:` on the next) is +# caught. Without this, code formatted as `.frame(\n maxWidth: …\n)` +# bypasses the lint silently — a real escape already present at +# ChatLoadingSkeleton.swift before this PR. ripgrep reports only the +# START line of a multiline match, so the comment filter (which only +# inspects that line) stays correct: the outer `.frame(` never itself +# starts with `//`. +RAW_HITS=$(rg -U --multiline-dotall -n --no-heading "$PATTERN" "${SCAN_DIRS[@]}" 2>/dev/null \ | grep -vE '^[^:]+:[0-9]+:[[:space:]]*//' \ || true) @@ -131,9 +140,17 @@ HEADER fi # Load the allowlist (strip comments + blank lines), preserving multiplicity. +# +# `grep -v` exits 1 when no lines match — under `set -euo pipefail` that +# would abort the script if the allowlist is ever header-only (e.g. after +# a full cleanup or `--update-baseline` with zero observed violations). +# `|| true` tolerates that edge case so a clean state stays clean. ALLOWLIST_ENTRIES="" if [[ -f "$ALLOWLIST_FILE" ]]; then - ALLOWLIST_ENTRIES=$(grep -vE '^([[:space:]]*#|[[:space:]]*$)' "$ALLOWLIST_FILE" | sort) + ALLOWLIST_RAW=$(grep -vE '^([[:space:]]*#|[[:space:]]*$)' "$ALLOWLIST_FILE" || true) + if [[ -n "$ALLOWLIST_RAW" ]]; then + ALLOWLIST_ENTRIES=$(printf '%s\n' "$ALLOWLIST_RAW" | sort) + fi fi # New violations = observed - allowlist (multiset difference preserved by `comm -23`). diff --git a/clients/scripts/flexframe-allowlist.txt b/clients/scripts/flexframe-allowlist.txt index 74ca2c8643f..ef3d9ac4c70 100644 --- a/clients/scripts/flexframe-allowlist.txt +++ b/clients/scripts/flexframe-allowlist.txt @@ -40,11 +40,13 @@ clients/macos/vellum-assistant/Features/Chat/ChatEmptyStateView.swift|.frame(max clients/macos/vellum-assistant/Features/Chat/ChatEmptyStateView.swift|.frame(maxWidth: VSpacing.chatBubbleMaxWidth) clients/macos/vellum-assistant/Features/Chat/ChatErrorToastView.swift|.frame(maxWidth: .infinity) clients/macos/vellum-assistant/Features/Chat/ChatErrorToastView.swift|.frame(maxWidth: .infinity, alignment: .leading) +clients/macos/vellum-assistant/Features/Chat/ChatLoadingSkeleton.swift|.frame( clients/macos/vellum-assistant/Features/Chat/ChatLoadingSkeleton.swift|.frame(maxWidth: .infinity, alignment: .trailing) clients/macos/vellum-assistant/Features/Chat/ChatLoadingSkeleton.swift|.frame(maxWidth: VSpacing.chatBubbleMaxWidth * 0.45, alignment: .trailing) clients/macos/vellum-assistant/Features/Chat/ChatLoadingSkeleton.swift|.frame(maxWidth: VSpacing.chatBubbleMaxWidth * 0.65) clients/macos/vellum-assistant/Features/Chat/ChatLoadingSkeleton.swift|.frame(maxWidth: VSpacing.chatBubbleMaxWidth, alignment: .leading) clients/macos/vellum-assistant/Features/Chat/ChatLoadingSkeleton.swift|.frame(maxWidth: VSpacing.chatColumnMaxWidth, alignment: .leading) +clients/macos/vellum-assistant/Features/Chat/ChatLoadingSkeleton.swift|maxWidth: VSpacing.chatBubbleMaxWidth * assistantLineWidths[idx], clients/macos/vellum-assistant/Features/Chat/ChatView.swift|.frame(maxWidth: .infinity, maxHeight: .infinity) clients/macos/vellum-assistant/Features/Chat/ChatView.swift|.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) clients/macos/vellum-assistant/Features/Chat/ChatView.swift|.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)