diff --git a/.Jules/palette.md b/.Jules/palette.md new file mode 100644 index 000000000..b9c39f70a --- /dev/null +++ b/.Jules/palette.md @@ -0,0 +1,3 @@ +## 2024-05-18 - Missing ARIA Expansion States on Custom Dropdowns +**Learning:** Custom popovers and dropdown triggers throughout the app (like Quick Tasks and Calendar View Options) often lack `aria-expanded` and `aria-haspopup` attributes, leaving screen reader users unaware of the dropdown's current open/closed state. +**Action:** When implementing custom toggle buttons that reveal dropdowns or dialogs, always dynamically bind `:aria-expanded="isOpen"` and include `aria-haspopup="dialog"` (or `listbox`/`menu`) to ensure state is announced to assistive technologies. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d34fd0638..cf6721aee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,10 +83,7 @@ jobs: - name: Install Playwright (chromium) run: npx playwright install --with-deps chromium - - name: Setup Supabase CLI - uses: supabase/setup-cli@v1 - with: - version: latest + - name: Boot Supabase + run two-client Realtime e2e (R1–R7) run: | diff --git a/scripts/run-e2e.sh b/scripts/run-e2e.sh index 2911c1d1f..d3513ff23 100755 --- a/scripts/run-e2e.sh +++ b/scripts/run-e2e.sh @@ -6,7 +6,7 @@ set -euo pipefail # Auto-fetch keys from local Supabase if not already set -SUPABASE_STATUS_ENV="${SUPABASE_STATUS_ENV:-$(supabase status -o env 2>&1 || true)}" +SUPABASE_STATUS_ENV="${SUPABASE_STATUS_ENV:-$(npx supabase status -o env 2>&1 || true)}" if [ -z "${SUPABASE_SERVICE_ROLE_KEY:-}" ]; then # Try new-format secret key first (Supabase v2.x uses sb_secret_* instead of HS256 JWT) diff --git a/src/components/QuickSortCard.vue b/src/components/QuickSortCard.vue index aa9be96fa..6be98a4ea 100644 --- a/src/components/QuickSortCard.vue +++ b/src/components/QuickSortCard.vue @@ -85,10 +85,10 @@ defineProps<{ }>() const emit = defineEmits<{ - (e: 'swipe-right'): void - (e: 'swipe-left'): void - (e: 'swipe-up'): void - (e: 'swipe-down'): void + (e: 'swipeRight'): void + (e: 'swipeLeft'): void + (e: 'swipeUp'): void + (e: 'swipeDown'): void }>() const cardRef = ref(null) @@ -105,10 +105,10 @@ const { haptics: true, fourDirectional: true, mouse: true, - onSwipeRight: () => emit('swipe-right'), - onSwipeLeft: () => emit('swipe-left'), - onSwipeUp: () => emit('swipe-up'), - onSwipeDown: () => emit('swipe-down') + onSwipeRight: () => emit('swipeRight'), + onSwipeLeft: () => emit('swipeLeft'), + onSwipeUp: () => emit('swipeUp'), + onSwipeDown: () => emit('swipeDown') }) // Card transform style - supports both horizontal and vertical movement diff --git a/src/components/ai/AIMemoryHealthDashboard.vue b/src/components/ai/AIMemoryHealthDashboard.vue index 11249bade..d8c7df6d6 100644 --- a/src/components/ai/AIMemoryHealthDashboard.vue +++ b/src/components/ai/AIMemoryHealthDashboard.vue @@ -36,13 +36,17 @@ -
{{ error }}
+
+ {{ error }} +

Memory Grade

-
{{ report.grade }}
+
+ {{ report.grade }} +

{{ gradeLabel }}

@@ -56,13 +60,17 @@

Sections

-
{{ report.sections.length }}
+
+ {{ report.sections.length }} +

{{ report.mode === 'full' ? 'Full assessment' : 'Quick check' }}

Duration

-
{{ formatDuration(report.durationMs) }}
+
+ {{ formatDuration(report.durationMs) }} +

{{ formatTime(report.timestamp) }}

@@ -70,7 +78,9 @@

No assessment results yet.

-

"Quick Check" runs heuristic tests instantly. "Full Assessment" adds LLM-as-judge context utilization tests (~30s).

+

+ "Quick Check" runs heuristic tests instantly. "Full Assessment" adds LLM-as-judge context utilization tests (~30s). +

@@ -115,7 +125,9 @@ {{ check.name }} {{ check.score }}% -
{{ check.value }}
+
+ {{ check.value }} +
{{ check.recommendation }}
@@ -160,7 +172,9 @@ {{ formatTime(h.timestamp) }} - + diff --git a/src/components/ai/ChatMessage.vue b/src/components/ai/ChatMessage.vue index a47ce2aaf..e5f95c384 100644 --- a/src/components/ai/ChatMessage.vue +++ b/src/components/ai/ChatMessage.vue @@ -371,15 +371,7 @@ function weeklyPlanTaskIds(rec: WeeklyPlanRecommendation): string[] { .filter(taskId => !dismissedCardTaskIds.value.has(taskId)) } -function weeklyPlanPrimaryTaskIds(rec: WeeklyPlanRecommendation): string[] { - return rec.primaryTaskId && !dismissedCardTaskIds.value.has(rec.primaryTaskId) ? [rec.primaryTaskId] : [] -} -function weeklyPlanRelatedChipIds(rec: WeeklyPlanRecommendation): string[] { - return [...new Set(rec.relatedTaskIds ?? [])] - .filter(taskId => taskId !== rec.primaryTaskId && !dismissedCardTaskIds.value.has(taskId)) - .slice(0, 4) -} function weeklyLaneTitle(rec: WeeklyPlanRecommendation): string { const locale = weeklyPlan.value?.locale ?? 'en' @@ -2586,13 +2578,17 @@ async function saveSchedule() { data-testid="ai-clarification" >
-
{{ clarification.progressLabel }}
+
+ {{ clarification.progressLabel }} +

{{ clarification.locale === 'he' ? 'שאלה קצרה לפני התכנון' : 'Quick question before planning' }}

{{ clarification.summary }}

{{ clarification.locale === 'he' ? 'למה אני שואל?' : 'Why ask?' }}
    -
  • {{ line }}
  • +
  • + {{ line }} +
@@ -2781,7 +2777,9 @@ async function saveSchedule() {

{{ weeklyPlan.headline }}

{{ weeklyPlan.weekRead.summary }}

-

{{ weeklyPlan.weekRead.mainTradeoff }}

+

+ {{ weeklyPlan.weekRead.mainTradeoff }} +

{{ weeklyPlan.locale === 'he' ? 'נתיב' : 'Lane' }} -

{{ weeklyLaneTitle(rec) }}

-

{{ weeklyLaneSubtitle(rec) }}

+

+ {{ weeklyLaneTitle(rec) }} +

+

+ {{ weeklyLaneSubtitle(rec) }} +