chore: overnight plan 2026-03-04 + /overnight command
- Rewrote loop/plan.md with 34 checkbox tasks across 8 phases - Updated loop/prompt.md for new overnight scope - Added .claude/commands/overnight.md skill - Self-destructing dev SW from previous session Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
8a1c3135dd
commit
9dbc9c24a6
+43
-68
@@ -1,84 +1,59 @@
|
||||
# Overnight Plan — iOS HIG Compliance & Continued Hardening
|
||||
# Overnight Plan — 2026-03-04
|
||||
|
||||
> **Format**: `- [ ]` = pending, `- [x]` = done.
|
||||
> Make at least 30 attempts on any difficult task before moving on. Loop reads this file.
|
||||
> After each phase, commit and push.
|
||||
## Phase 1: Critical Fixes
|
||||
|
||||
## Phase 1: Input & Text Foundation (Prevent iOS Zoom + Readability)
|
||||
- [ ] P1-1: Brighten SVG fallbacks — increase background lightness from 18% to 28% across all 8 generators in `useImageFallback.ts` (generateSongCoverFallback, generatePodcastCoverFallback, generateNewsFallback, generateImageFallback, generatePosterFallback, generateTVSeriesFallback, generateBookCoverFallback, generatePlaceFallback). Proportionally increase all inner element lightness by +10%. TEST: run `pnpm typecheck` and visually confirm SVGs generate valid data URIs.
|
||||
- [ ] P1-2: Add `.catch(() => {})` to all cover fetch promise chains in grid components — SongGrid.vue (line 157), FilmGrid.vue (line 143), TVSeriesGrid.vue (line 160), BookGrid.vue (line 141), PodcastGrid.vue (line 130). Prevents unhandled rejection if fetch throws unexpectedly. TEST: `pnpm typecheck && pnpm lint`.
|
||||
- [ ] P1-3: Refine mobile keyboard handling — In `useVisualViewport.ts`, add debounce to viewport change handler (50ms) to prevent jittery resizing. In `App.vue`, ensure the `rootStyle` computed applies `overflow: hidden` when keyboard is open. TEST: `pnpm typecheck`.
|
||||
- [ ] P1-4: Verify service worker cleanup — Confirm `dev-dist/sw.js` contains the self-destructing SW and `vite.config.ts` has `devOptions.enabled: false`. If not, fix. TEST: read both files and verify.
|
||||
|
||||
- [x] **T1** — Fix all input/textarea font sizes to prevent iOS auto-zoom. Every `<input>`, `<textarea>`, and `<select>` must use `text-base` (16px) minimum. Files to fix: `ChatInput.vue` (main message textarea uses `text-sm`), `ChatSearch.vue` (search input), `SettingsModal.vue` (memory inputs use `text-xs`), `PersonaSelector.vue`, `MemoryPanel.vue`, `PluginSettingsForm.vue`, `ShareToNostr.vue`, `AdvancedSettings.vue`, `PromptPalette.vue`. Search for all `<input` and `<textarea` tags across `packages/app/src/` and verify each has at least `text-base`. Do NOT change the visual design — only increase font size on the form elements themselves.
|
||||
## Phase 2: Error Handling Hardening
|
||||
|
||||
- [x] **T2** — Replace all `text-[10px]` with `text-xs` (12px) across the entire app. There are ~301 instances. Use find-and-replace but verify each file still looks correct. The main offenders: `ChatMessage.vue` (timestamps, token counts, edit labels), `SettingsModal.vue` (section headers), `ContentPanel.vue` (tab labels), all `*Detail.vue` and `*Grid.vue` files. Run `grep -r 'text-\[10px\]' packages/app/src/` to find all instances. Replace with `text-xs`. This is the single biggest compliance fix.
|
||||
- [ ] P2-1: Wrap JSON.parse calls in try/catch — `useContentDiscovery.ts` sessionStorage parse, all sessionStorage/localStorage reads in composables. Search for `JSON.parse` across all `.ts` and `.vue` files, wrap any unprotected calls. TEST: `pnpm typecheck && pnpm lint`.
|
||||
- [ ] P2-2: Add `.ok` checks before `.json()` on fetch calls — `useBitcoinPrice.ts` (Mempool API), `MempoolTxCard.vue` (tip height), `useNip05Verification.ts` (NIP-05 lookup), `ZapDialog.vue` (Lightning address). Search for `fetch(` → `.json()` patterns without `.ok` check. TEST: `pnpm typecheck && pnpm lint`.
|
||||
- [ ] P2-3: Harden SSE streaming — In `useAI.ts` `readSSE()`, wrap `reader.read()` in try/catch, close reader on error. In `openrouter-adapter.ts`, add same pattern. TEST: `pnpm typecheck`.
|
||||
- [ ] P2-4: Add error handling to async watchers — `PdfViewer.vue` watch calling `renderPage()`, `VideoPlayer.vue` `initHls()` in onMounted. Wrap in try/catch with user-friendly error state. TEST: `pnpm typecheck`.
|
||||
|
||||
- [x] **T3** — Replace all `text-[9px]` and `text-[8px]` with `text-[11px]` (iOS absolute minimum). There are ~100 instances. These are used in badges, version numbers, metadata labels. Files: `PluginMarketplace.vue`, `NostrGrid.vue`, `DesignSystemDetail.vue`, `DesignSystemGrid.vue`, settings components. Search with `grep -r 'text-\[9px\]\|text-\[8px\]' packages/app/src/`. Replace with `text-[11px]`.
|
||||
## Phase 3: Security Hardening
|
||||
|
||||
- [x] **T4** — Replace all `text-[11px]` with `text-xs` (12px). There are ~76 instances plus the new ones from T3. These are in `SettingsModal.vue`, `BranchSwitcher.vue`, `DesignSystemGrid.vue`. After T3 creates new `text-[11px]` instances, this task bumps them all to `text-xs`. Search with `grep -r 'text-\[11px\]' packages/app/src/`. Replace with `text-xs`.
|
||||
- [ ] P3-1: postMessage origin validation — In `archyBridge.ts`, replace `'*'` targetOrigin with configurable origin. Add origin check on incoming message handler. TEST: `pnpm typecheck`.
|
||||
- [ ] P3-2: URL validation — In `contentExtraction.ts`, add URL length limit (2048 chars) to `extractUrlFromText()`. Validate URLs before fetch. TEST: `pnpm typecheck && pnpm lint`.
|
||||
- [ ] P3-3: Content sanitization — Review `html.ts` for innerHTML usage, ensure SVG injection is covered. Replace `innerHTML = ''` with `textContent = ''` in `usePlayer.ts`. TEST: `pnpm typecheck`.
|
||||
- [ ] P3-4: Add CSP meta tag — Add `<meta http-equiv="Content-Security-Policy" ...>` to `index.html` with appropriate directives for the app (allow self, API hosts, image CDNs). TEST: `pnpm typecheck`.
|
||||
|
||||
- [x] **TEST:P1** — Run `pnpm typecheck && pnpm lint && pnpm test`. Fix all failures. Commit and push.
|
||||
## Phase 4: Test Suite
|
||||
|
||||
## Phase 2: Touch Targets — Chat Interface (44×44px Minimum)
|
||||
- [ ] P4-1: Unit tests for usePlayer — Create `packages/app/src/composables/__tests__/usePlayer.test.ts`. Test playback state, queue management, play/pause/next/prev. Minimum 8 test cases. TEST: `pnpm test`.
|
||||
- [ ] P4-2: Unit tests for useContentPanel — Create `packages/app/src/composables/__tests__/useContentPanel.test.ts`. Test tab switching, detail opening, panel state management. Minimum 6 test cases. TEST: `pnpm test`.
|
||||
- [ ] P4-3: Unit tests for useVisualViewport — Create `packages/app/src/composables/__tests__/useVisualViewport.test.ts`. Mock visualViewport API, test keyboard detection, viewport height calculation. Minimum 5 test cases. TEST: `pnpm test`.
|
||||
- [ ] P4-4: Content extraction edge case tests — Create `packages/app/src/composables/__tests__/contentExtraction.test.ts`. Test interleaved tags, malformed tags, unicode content, missing fields. Minimum 10 test cases. TEST: `pnpm test`.
|
||||
- [ ] P4-5: Seeded prompt regression tests — Create `packages/app/src/__tests__/seed-conversations.test.ts`. Import all seed conversations from mocks, run content extraction on each, verify expected content types are produced. Minimum 1 test per seed. TEST: `pnpm test`.
|
||||
|
||||
- [x] **T5** — Fix ChatMessage.vue action buttons. The edit/reply/branch/feedback buttons use `w-7 h-7` (28px). Change the button wrapper to `min-w-[44px] min-h-[44px]` with `flex items-center justify-center` while keeping the inner SVG icon at `w-4 h-4` or `w-5 h-5`. This makes the tap target 44px but the visual icon stays the same size. Also fix the `gap-0.5` (2px) between action buttons to `gap-2` (8px). Apply to all button rows in this file.
|
||||
## Phase 5: Feature Work
|
||||
|
||||
- [x] **T6** — Fix ChatHeader.vue toolbar buttons. All 9 buttons use `w-8 h-8` or `w-9 h-9` (32-36px). Wrap each in a 44px touch target: `min-w-[44px] min-h-[44px] flex items-center justify-center`. Keep the visual icon sizes unchanged. Fix any `gap-1` between toolbar buttons to `gap-2`.
|
||||
- [ ] P5-1: File browser page — Create `packages/app/src/pages/BrowsePage.vue` with file tree navigation. Add route `/browse` to router. Use the existing `vite-fs.ts` plugin for file reading. Show files/folders with icons, breadcrumb nav. TEST: `pnpm typecheck && pnpm lint`.
|
||||
- [ ] P5-2: File tree component — Create `packages/app/src/components/browse/FileTree.vue`. Recursive tree with expand/collapse, file type icons (folder, code, image, document). Use glass morphism styling. TEST: `pnpm typecheck`.
|
||||
- [ ] P5-3: File preview component — Create `packages/app/src/components/browse/FilePreview.vue`. Preview text files with syntax highlighting (reuse code viewer), images inline, show file metadata. TEST: `pnpm typecheck`.
|
||||
- [ ] P5-4: Allow .claude folder in code viewer — Update `vite-fs.ts` to allow `.claude/` path. Update any path validation that blocks dotfiles. Show CLAUDE.md, settings, hooks, memory files. TEST: `pnpm typecheck`.
|
||||
- [ ] P5-5: Archy local search guide — Create `packages/app/src/docs/archy-local-search.md` documenting how file types map to content surfaces (images→ImageGrid, music→SongGrid, etc.), how ContextBroker filtering works. Also add a help section component that can display this in-app. TEST: file exists and is valid markdown.
|
||||
|
||||
- [x] **T7** — Fix ChatInput.vue buttons. The image attach button (`w-8 h-8`), close reply button (`w-5 h-5`), and send button need 44px minimum touch targets. Also fix the send button row gap to 8px minimum between targets.
|
||||
## Phase 6: Accessibility
|
||||
|
||||
- [x] **T8** — Fix ChatSearch.vue navigation buttons. Previous/Next/Close buttons use `w-6 h-6` (24px). Expand to 44px touch targets with padding.
|
||||
- [ ] P6-1: Add aria-labels to icon buttons — Audit all icon-only buttons across chat components (ChatHeader.vue, ChatMessage.vue, ChatInput.vue, ChatSearch.vue). Add descriptive `aria-label` to each. TEST: `pnpm lint`.
|
||||
- [ ] P6-2: Add aria-labels to content grids — All Grid components (SongGrid, FilmGrid, TVSeriesGrid, PlaceGrid, BookGrid, PodcastGrid, NewsGrid, ImageGrid). Each card button needs `aria-label` with content title. TEST: `pnpm lint`.
|
||||
- [ ] P6-3: Focus management for dialogs — `ZapDialog.vue`: add focus trap, auto-focus close button, `aria-modal="true"`, `role="dialog"`. Same for `SettingsModal.vue`. Ensure Escape key closes. TEST: `pnpm typecheck`.
|
||||
- [ ] P6-4: Color contrast audit — Check `text-white/40` against dark backgrounds for WCAG AA (4.5:1). Verify `#F7931A` accent contrast. Fix any failing ratios by increasing opacity. Document findings in comments. TEST: `pnpm lint`.
|
||||
- [ ] P6-5: Alt text improvements — `ImageGrid.vue`: use `img.title || img.alt` instead of generic. All content grids: ensure img alt includes meaningful content (title + artist/director/author). TEST: `pnpm lint`.
|
||||
|
||||
- [x] **T9** — Fix ArticleReader.vue and PdfViewer.vue controls. Close/navigation buttons use `w-8 h-8` (32px). Expand to 44px. Fix button gaps.
|
||||
## Phase 7: Performance & Compatibility
|
||||
|
||||
- [x] **TEST:P2** — Run `pnpm typecheck && pnpm lint && pnpm test`. Commit and push.
|
||||
- [ ] P7-1: Lazy load heavy renderers — Use `defineAsyncComponent` for PdfViewer, VideoPlayer, MapView. Add loading skeleton components for each. TEST: `pnpm typecheck`.
|
||||
- [ ] P7-2: Add in-memory caching — `useNip05Verification.ts`: cache results with 5-min TTL. `useBitcoinPrice.ts`: cache price with 30s TTL. TEST: `pnpm typecheck`.
|
||||
- [ ] P7-3: Error boundaries for grid items — Create `packages/app/src/components/ui/ErrorBoundary.vue` using `onErrorCaptured`. Wrap each grid item renderer to prevent cascade failures. Show fallback UI on component crash. TEST: `pnpm typecheck`.
|
||||
- [ ] P7-4: Code file size limits — In `useCodeContext.ts` `openFile()`, add file size check before reading (reject > 1MB). Add loading indicator for large files. TEST: `pnpm typecheck`.
|
||||
|
||||
## Phase 3: Touch Targets — Content & Settings Components
|
||||
## Phase 8: Research & Documentation
|
||||
|
||||
- [x] **T10** — Fix all content detail view buttons. Search for `w-7 h-7`, `w-6 h-6`, `w-5 h-5` button patterns in: `BookDetail.vue`, `FilmDetail.vue`, `TVSeriesDetail.vue`, `SongDetail.vue`, `PodcastDetail.vue`, `PlaceDetail.vue`, `ImageDetail.vue`, `AppDetail.vue`, `MagazineSectionDetail.vue`, `NostrGrid.vue`. Expand all interactive buttons to 44px minimum touch targets. Keep icon sizes unchanged.
|
||||
|
||||
- [x] **T11** — Fix SettingsModal.vue and SettingsPanel.vue buttons. Close button (`w-7 h-7`), color picker buttons (`w-8 h-8`), edit/delete buttons (`w-5 h-5`). All need 44px. Fix all `gap-0.5` to `gap-2`.
|
||||
|
||||
- [x] **T12** — Fix MemoryPanel.vue, PersonaSelector.vue, and PluginMarketplace.vue buttons. Edit/delete memory buttons (`w-5 h-5`), persona buttons, plugin action buttons. All need 44px touch targets with 8px gaps.
|
||||
|
||||
- [x] **T13** — Fix MapRenderer.vue fullscreen button, BranchSwitcher.vue buttons, and any remaining small buttons found by searching for `w-5 h-5`, `w-6 h-6`, `w-7 h-7`, `w-8 h-8` on clickable elements across all `.vue` files. Each interactive element needs 44px minimum.
|
||||
|
||||
- [x] **TEST:P3** — Run `pnpm typecheck && pnpm lint && pnpm test`. Commit and push.
|
||||
|
||||
## Phase 4: Touch Target Gaps & ContentPanel Tab Bar
|
||||
|
||||
- [x] **T14** — Fix ContentPanel.vue tab bar. Tab buttons likely have `gap-1` (4px) between them. Increase to `gap-2` (8px). Ensure each tab button has at least 44px height. The tab labels should use `text-xs` minimum (from Phase 1 fixes). The tab bar should be horizontally scrollable on mobile with sufficient padding.
|
||||
|
||||
- [x] **T15** — Audit and fix ALL remaining `gap-0.5` and `gap-1` between clickable elements. Search all `.vue` files for `gap-0.5` and `gap-1`. For each result, check if the container holds clickable elements (buttons, links, tabs). If so, increase to `gap-2` (8px). Leave non-clickable layout gaps (like text spacing) unchanged.
|
||||
|
||||
- [x] **T16** — Fix grid card touch targets. In all `*Grid.vue` components, verify that cards have sufficient tap area. Cards themselves are usually fine (full-width), but action buttons within cards (favorite, play, expand) need 44px targets. Check: `FilmGrid.vue`, `SongGrid.vue`, `BookGrid.vue`, `TVSeriesGrid.vue`, `PodcastGrid.vue`, `AppsGrid.vue`, `ArchyAppsGrid.vue`, `ImageGrid.vue`, `PlaceGrid.vue`.
|
||||
|
||||
- [x] **TEST:P4** — Run `pnpm typecheck && pnpm lint && pnpm test`. Commit and push.
|
||||
|
||||
## Phase 5: Glass Button System & Utility Classes
|
||||
|
||||
- [x] **T17** — Update `.glass-button` and `.glass-button-sm` in `packages/app/src/styles/main.css` to enforce 44px minimum height on mobile. Add a responsive rule: on screens ≤ 768px, `.glass-button` gets `min-height: 48px` and `.glass-button-sm` gets `min-height: 44px`. This catches all uses of these classes automatically. On desktop they stay as-is.
|
||||
|
||||
- [x] **T18** — Audit all `!h-7 !min-h-0` overrides. These force 28px height, defeating the glass button minimum. Search all `.vue` files for `!h-7` and `!min-h-0`. Replace with mobile-responsive approach: keep desktop size but ensure 44px minimum on mobile using `min-h-[44px] md:min-h-0`.
|
||||
|
||||
- [x] **T19** — Add a `.touch-target` utility class to `main.css`: `.touch-target { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }`. Then refactor at least 15 icon buttons across the app to use this class instead of manual min-w/min-h. This creates a reusable pattern for future development.
|
||||
|
||||
- [x] **TEST:P5** — Run `pnpm typecheck && pnpm lint && pnpm test`. Commit and push.
|
||||
|
||||
## Phase 6: Modals, Dialogs & Overlays
|
||||
|
||||
- [x] **T20** — Fix PassphraseDialog.vue. Submit button uses `h-10` (40px, 4px short). Change to `h-11` (44px). Verify input field is `text-base`. Ensure the dialog has proper padding for mobile.
|
||||
|
||||
- [x] **T21** — Audit all modal/overlay/dialog components for mobile compliance. Check: `ArticleOverlay.vue`, `ShareToNostr.vue`, `ConversationExport.vue`, `ComparisonMode.vue`, `NostrProfileEditor.vue`, `NostrRelayManager.vue`. Each should have: 44px button touch targets, 16px input text, 8px button gaps, proper padding on mobile.
|
||||
|
||||
- [x] **T22** — Fix the sidebar/conversation list touch targets. `ConversationList.vue` or sidebar entries should have at least 44px height per item. Delete/rename buttons within list items need 44px targets.
|
||||
|
||||
- [x] **TEST:P6** — Run `pnpm typecheck && pnpm lint && pnpm test`. Commit and push.
|
||||
|
||||
## Phase 7: Comprehensive Verification
|
||||
|
||||
- [ ] **T23** — Run a final grep audit to verify NO remaining violations:
|
||||
- `text-[10px]`, `text-[9px]`, `text-[8px]` — should return 0 results in `packages/app/src/`
|
||||
- `text-[11px]` — should return 0 results (all bumped to text-xs)
|
||||
- `gap-0.5` between clickable elements — should be 0
|
||||
- All inputs have `text-base` minimum
|
||||
Fix any remaining violations found.
|
||||
|
||||
- [ ] **T24** — Run `pnpm test` (all tests pass), `pnpm typecheck` (no errors), `pnpm lint` (0 errors). Final commit with summary message. Push to remote.
|
||||
- [ ] P8-1: iOS app research — Research Capacitor vs WKWebView wrapper vs React Native WebView for shipping AIUI as iOS app. Document in `docs/research/ios-app.md`: pros/cons, App Store requirements, push notification integration, offline capability. Include concrete next steps.
|
||||
- [ ] P8-2: Mac desktop app research — Research Tauri v2 vs Electron for Mac desktop app. Document in `docs/research/mac-desktop.md`: binary size, memory usage, menu bar app pattern (like Raycast), global hotkey/command invocation, tray API. Include concrete next steps.
|
||||
- [ ] P8-3: Plugin system hardening research — Document in `docs/research/plugin-security.md`: signature validation for community plugins, sandboxed iframe execution, permission system per plugin. Reference existing plugin interfaces in `packages/core/src/plugins/`.
|
||||
|
||||
+56
-85
@@ -1,102 +1,73 @@
|
||||
You are making the AIUI app compliant with iOS Human Interface Guidelines (HIG) for font sizes, touch targets, and button hitboxes — WITHOUT changing the visual design. Read these files first:
|
||||
You are working through an overnight automation plan for the AIUI app. Read these files first:
|
||||
|
||||
1. `loop/plan.md` — Your task checklist (mark items `- [x]` as you complete them)
|
||||
2. `CLAUDE.md` — Project conventions, design system rules, and coding standards
|
||||
|
||||
## Key Principle
|
||||
## Project Context
|
||||
|
||||
**Same design, better accessibility.** The app should look identical but be properly tappable and readable on mobile. All changes are about sizing minimums, not visual redesign.
|
||||
AIUI is an AI content surface UI — a Vue 3 + TypeScript + Tailwind CSS app with chat, content panels (films, music, books, TV, places, news, images, podcasts), and a plugin system. It runs as a PWA and inside Archy (an iframe host).
|
||||
|
||||
## iOS HIG Requirements
|
||||
Key directories:
|
||||
- `packages/app/src/` — Main application source
|
||||
- `packages/app/src/composables/` — Shared composition functions
|
||||
- `packages/app/src/components/content/` — Content grid and detail components
|
||||
- `packages/app/src/components/chat/` — Chat interface components
|
||||
- `packages/app/src/styles/main.css` — Glass morphism design system
|
||||
- `packages/core/src/` — Core library and types
|
||||
|
||||
1. **Font Sizes:**
|
||||
- Body text: 17px (but we use 14px base — OK, it's a dense app)
|
||||
- Footnote: 13px minimum
|
||||
- Caption: 11px ABSOLUTE minimum (nothing smaller than 11px ever)
|
||||
- Form inputs: 16px minimum (prevents iOS auto-zoom on focus)
|
||||
## Working Process
|
||||
|
||||
2. **Touch Targets:**
|
||||
- All interactive elements: 44×44px minimum tappable area
|
||||
- The VISUAL icon can be smaller (e.g., 20px SVG), but the tappable wrapper must be 44×44px
|
||||
- Pattern: `<button class="min-w-[44px] min-h-[44px] flex items-center justify-center"><svg class="w-5 h-5" ...></button>`
|
||||
|
||||
3. **Gaps Between Targets:**
|
||||
- Minimum 8px (gap-2) between any two tappable elements
|
||||
- `gap-0.5` (2px) and `gap-1` (4px) between buttons is a violation
|
||||
|
||||
## Current Violations Found (from audit)
|
||||
|
||||
- **301× `text-[10px]`** — timestamps, labels, metadata throughout app
|
||||
- **76× `text-[11px]`** — settings, branch switcher, design system
|
||||
- **100× `text-[9px]` / `text-[8px]`** — badges, version numbers, plugin metadata
|
||||
- **40+ buttons below 44×44px** — `w-7 h-7` (28px), `w-8 h-8` (32px), `w-6 h-6` (24px), `w-5 h-5` (20px)
|
||||
- **20+ locations with gap < 8px** between clickable elements
|
||||
- **9+ inputs below 16px** — ChatInput textarea, settings inputs, search
|
||||
|
||||
## Key Files
|
||||
|
||||
- `packages/app/src/styles/main.css` — Glass button system, utility classes
|
||||
- `packages/app/src/components/chat/ChatMessage.vue` — Message actions, timestamps
|
||||
- `packages/app/src/components/chat/ChatInput.vue` — Main input, send button
|
||||
- `packages/app/src/components/chat/ChatHeader.vue` — Toolbar buttons
|
||||
- `packages/app/src/components/chat/ChatSearch.vue` — Search nav buttons
|
||||
- `packages/app/src/components/chat/SettingsModal.vue` — Settings UI
|
||||
- `packages/app/src/components/content/ContentPanel.vue` — Tab bar
|
||||
- `packages/app/src/components/content/*Grid.vue` — All content grids
|
||||
- `packages/app/src/components/content/*Detail.vue` — All detail views
|
||||
- `packages/app/src/components/settings/` — Settings components
|
||||
- `packages/app/src/components/ui/` — Shared UI components
|
||||
|
||||
## Design System Rules (must follow for every file you touch)
|
||||
|
||||
- **Glass morphism only** — use `.glass`, `.glass-card`, `.glass-button`, `.glass-button-sm` from `src/styles/main.css`
|
||||
- **No light-mode conditionals** — never use `isDark ?` pattern. The app is dark-only.
|
||||
- **No `bg-gray-*` or `bg-white`** — use `bg-white/5`, `bg-white/10`, `bg-black/35` etc.
|
||||
- **Text opacity scale** — `text-white/25` → `/40` → `/60` → `/70` → `/80` → `/90` → `/96` → `text-white`
|
||||
- **Accent colour** — `text-accent` (`#F7931A`), `bg-accent/15`, `border-accent/30`
|
||||
- **Animations** — `animate-scale-in`, `animate-fade-up`, `animate-fade-in` from design system only
|
||||
|
||||
## How to Fix Touch Targets (Pattern)
|
||||
|
||||
**Before (violation):**
|
||||
```html
|
||||
<button class="w-7 h-7 rounded-full" @click="doThing">
|
||||
<svg class="w-4 h-4" ...></svg>
|
||||
</button>
|
||||
```
|
||||
|
||||
**After (compliant):**
|
||||
```html
|
||||
<button class="min-w-[44px] min-h-[44px] flex items-center justify-center rounded-full" @click="doThing">
|
||||
<svg class="w-4 h-4" ...></svg>
|
||||
</button>
|
||||
```
|
||||
|
||||
Or use the utility class (after T19):
|
||||
```html
|
||||
<button class="touch-target rounded-full" @click="doThing">
|
||||
<svg class="w-4 h-4" ...></svg>
|
||||
</button>
|
||||
```
|
||||
|
||||
## For each task in loop/plan.md:
|
||||
For each task in `loop/plan.md`:
|
||||
|
||||
1. Find the first unchecked `- [ ]` item
|
||||
2. Read the task description carefully
|
||||
2. Read the task description carefully — it tells you what to change and where
|
||||
3. Read the relevant source files before making changes
|
||||
4. Make the change — keep visual design identical, only adjust sizing
|
||||
5. Run `pnpm typecheck && pnpm lint` — fix all errors
|
||||
6. Run `pnpm test` — fix any failing tests
|
||||
7. Commit: `type(scope): description` (conventional commits)
|
||||
8. Mark it done `- [x]` in `loop/plan.md`
|
||||
4. Make the change following CLAUDE.md conventions
|
||||
5. Run the TEST command specified in the task
|
||||
6. Fix any errors from the test command before proceeding
|
||||
7. Commit with conventional commit format: `type(scope): description`
|
||||
8. Mark the task done: change `- [ ]` to `- [x]` in `loop/plan.md`
|
||||
9. Move to the next unchecked task immediately
|
||||
|
||||
## Testing Gates
|
||||
|
||||
Every task specifies a TEST command. You MUST run it and pass before committing:
|
||||
- `pnpm typecheck` — TypeScript strict mode compilation
|
||||
- `pnpm lint` — ESLint checks
|
||||
- `pnpm test` — Vitest unit tests
|
||||
- Multiple commands joined with `&&` must ALL pass
|
||||
|
||||
If a test fails, fix the issue and re-run. Do not skip tests. Do not mark a task as done if tests fail.
|
||||
|
||||
## Coding Rules
|
||||
|
||||
- **Vue 3 Composition API only** — `<script setup lang="ts">`, never Options API
|
||||
- **Glass morphism design** — use `.glass`, `.glass-card`, `.glass-button` from `main.css`
|
||||
- **Dark theme** — `bg-white/5`, `text-white/80`, never `bg-gray-*` or plain `bg-white`
|
||||
- **Text opacity scale** — `text-white/25` → `/40` → `/60` → `/70` → `/80` → `/90` → `/96`
|
||||
- **Accent** — `text-accent` (`#F7931A`)
|
||||
- **Touch targets** — minimum 44x44px for all interactive elements
|
||||
- **Font minimums** — never smaller than 11px
|
||||
- **No over-engineering** — only change what the task asks for
|
||||
- **Keep existing patterns** — match the style of surrounding code
|
||||
|
||||
## Commit Format
|
||||
|
||||
```
|
||||
type(scope): description
|
||||
|
||||
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
||||
```
|
||||
|
||||
Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`
|
||||
Scope: `app`, `core`, or specific area like `chat`, `content`, `player`
|
||||
|
||||
## Rules
|
||||
|
||||
- Never skip a testing gate — if tests fail, fix them before moving on
|
||||
- If a task is proving difficult, keep trying different approaches. Make at least 30 genuine attempts.
|
||||
- Always run typecheck + lint after every code change
|
||||
- The visual design must NOT change — same colors, same layout, same glass morphism
|
||||
- Only sizes of tappable areas, font minimums, and gaps change
|
||||
- If a task is proving difficult, make at least 10 genuine attempts before moving on
|
||||
- Always read source files before editing them
|
||||
- Do not stop until all tasks are checked or you are rate limited
|
||||
- Commit and push after each TEST: task
|
||||
- Commit after each completed task
|
||||
- For research tasks (Phase 8), create the docs directory if needed: `mkdir -p docs/research`
|
||||
- For test tasks (Phase 4), create the test directory if needed: `mkdir -p packages/app/src/composables/__tests__`
|
||||
|
||||
Reference in New Issue
Block a user