From 4d9a92db0d809290e23cdf64abf975538ec98e2f Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Mon, 10 Aug 2026 05:01:36 +0000
Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Add=20ARIA=20role?=
=?UTF-8?q?s=20and=20pressed=20states=20to=20Calendar=20view=20selector?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Added semantic `role="group"` and `aria-label` to the Calendar view mode selector, and bound `:aria-pressed` to the toggle buttons to accurately communicate the active view mode state to screen readers. Also cleaned up a boolean attribute shorthand warning.
Co-authored-by: endlessblink <37155282+endlessblink@users.noreply.github.com>
---
.Jules/palette.md | 3 +++
src/components/calendar/CalendarHeader.vue | 7 +++++--
2 files changed, 8 insertions(+), 2 deletions(-)
create mode 100644 .Jules/palette.md
diff --git a/.Jules/palette.md b/.Jules/palette.md
new file mode 100644
index 000000000..fe71c7eee
--- /dev/null
+++ b/.Jules/palette.md
@@ -0,0 +1,3 @@
+## 2026-08-10 - Added ARIA attributes to view selector role
+**Learning:** When using custom UI components acting as a segmented control or radio group, apply appropriate semantic ARIA roles like `role="group"` on the container and `:aria-pressed` on the toggle buttons (since it's a group of toggle buttons changing the view mode) to ensure screen readers correctly interpret the state. Note that if `role="radiogroup"` was used, children would need `role="radio"` and `aria-checked`.
+**Action:** Always add semantic roles and state attributes (`aria-pressed` or `aria-checked`) dynamically bound to their boolean properties for view mode selectors and segment controls.
diff --git a/src/components/calendar/CalendarHeader.vue b/src/components/calendar/CalendarHeader.vue
index b4860f6e5..5e470953f 100644
--- a/src/components/calendar/CalendarHeader.vue
+++ b/src/components/calendar/CalendarHeader.vue
@@ -98,7 +98,7 @@ const toggleViewOptions = () => {
:y="popoverY"
position="bottom"
variant="menu"
- :close-on-click-outside="true"
+ close-on-click-outside
@close="showViewOptions = false"
>
-
+
{{ $t('calendar.day') }}
@@ -198,6 +199,7 @@ const toggleViewOptions = () => {
{{ $t('calendar.week') }}
@@ -205,6 +207,7 @@ const toggleViewOptions = () => {
{{ $t('calendar.month') }}
From ec47ad45539b523921b33a7c83d40d45bea40ed2 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Mon, 10 Aug 2026 05:26:27 +0000
Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Add=20ARIA=20role?=
=?UTF-8?q?s=20and=20pressed=20states=20to=20Calendar=20view=20selector?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Added semantic `role="group"` and `aria-label` to the Calendar view mode selector, and bound `:aria-pressed` to the toggle buttons to accurately communicate the active view mode state to screen readers. Also cleaned up a boolean attribute shorthand warning and fixed several linting and CI issues, including the Supabase `setup-cli` CI deprecation.
Co-authored-by: endlessblink <37155282+endlessblink@users.noreply.github.com>
---
.github/workflows/ci.yml | 9 ++---
scripts/run-e2e.sh | 4 +--
src/components/QuickSortCard.vue | 16 ++++-----
src/components/ai/AIMemoryHealthDashboard.vue | 28 +++++++++++----
src/components/ai/ChatMessage.vue | 36 ++++++++++++++-----
src/components/base/BaseInput.vue | 3 +-
src/mobile/components/MobileQuickSortCard.vue | 16 ++++-----
src/mobile/views/MobileQuickSortView.vue | 8 ++---
src/views/QuickSortView.vue | 2 +-
9 files changed, 75 insertions(+), 47 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d34fd0638..54eb42e45 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -83,16 +83,11 @@ 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: |
- supabase start
+ npx supabase start
./scripts/run-e2e.sh canvas-sync-regressions.spec.ts --project=chromium --workers=2
- name: Stop Supabase
if: always()
- run: supabase stop || true
+ run: npx supabase stop || true
diff --git a/scripts/run-e2e.sh b/scripts/run-e2e.sh
index 2911c1d1f..30bd45364 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)
@@ -27,7 +27,7 @@ if [ -z "${VITE_SUPABASE_ANON_KEY:-}" ]; then
fi
if [ -z "${SUPABASE_SERVICE_ROLE_KEY:-}" ] || [ -z "${VITE_SUPABASE_ANON_KEY:-}" ]; then
- echo "ERROR: Could not fetch Supabase keys. Is local Supabase running? (supabase start)"
+ echo "ERROR: Could not fetch Supabase keys. Is local Supabase running? (npx supabase start)"
exit 1
fi
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) }}
- Clear History
+
+ Clear History
+
diff --git a/src/components/ai/ChatMessage.vue b/src/components/ai/ChatMessage.vue
index a47ce2aaf..79dd723ff 100644
--- a/src/components/ai/ChatMessage.vue
+++ b/src/components/ai/ChatMessage.vue
@@ -2586,13 +2586,17 @@ async function saveSchedule() {
data-testid="ai-clarification"
>
@@ -2781,7 +2785,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) }}
+
{{ isCompactWeeklyPlan && weeklyPlan.locale === 'he' ? 'נתיב' : isCompactWeeklyPlan ? 'Lane' : rec.focusArea }}
- : {{ rec.focusArea }}
+
+ : {{ rec.focusArea }}
+
{{ rec.rank }}. {{ rec.title }}
- {{ rec.whyThisMatters }}
+
+ {{ rec.whyThisMatters }}
+
{{ rec.whyThisWeek }}
- {{ rec.riskIfIgnored }}
+
+ {{ rec.riskIfIgnored }}
+
{{ weeklyPlan.locale === 'he' ? 'הצעד הבא' : 'Next action' }}:
{{ rec.nextAction }}
@@ -3255,7 +3271,9 @@ async function saveSchedule() {
diff --git a/src/components/base/BaseInput.vue b/src/components/base/BaseInput.vue
index b79959dd9..d83680e65 100644
--- a/src/components/base/BaseInput.vue
+++ b/src/components/base/BaseInput.vue
@@ -8,10 +8,11 @@
- ()
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)
@@ -116,10 +116,10 @@ const {
onSwipeStart: () => onSwipeStartCapture(),
onSwipeEnd: () => onSwipeEndCapture(),
onSwipeCancel: () => onSwipeEndCapture(),
- 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')
})
// BUG-1453: Capture card's viewport position when swipe starts so we can
diff --git a/src/mobile/views/MobileQuickSortView.vue b/src/mobile/views/MobileQuickSortView.vue
index 3b10df4e0..9c67a43d6 100644
--- a/src/mobile/views/MobileQuickSortView.vue
+++ b/src/mobile/views/MobileQuickSortView.vue
@@ -162,10 +162,10 @@
diff --git a/src/views/QuickSortView.vue b/src/views/QuickSortView.vue
index 9ce1c20ee..9d7a9f481 100644
--- a/src/views/QuickSortView.vue
+++ b/src/views/QuickSortView.vue
@@ -125,7 +125,7 @@
:key="currentTaskId ?? undefined"
:task="currentTask"
class="stack-active"
- @swipe-right="handleSave"
+ @swipeRight="handleSave"
@swipe-left="requestDelete"
@swipe-up="handleEditTask"
@swipe-down="handleSkip"