Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
5bde401
chore(release): bump version to 2.3.0-beta.1
hessius Mar 12, 2026
0e6d825
refactor: extract parseStructuredAnalysis and SectionCard to shared m…
hessius Mar 12, 2026
bd40c6c
feat(#258): analysis-to-edit pipeline with recommendation selection
hessius Mar 12, 2026
7be5c09
feat(#95): profile recommendation system with tag-based scoring and L…
hessius Mar 12, 2026
0b513fd
refactor(web): decompose ShotHistoryView monolith into sub-components…
hessius Mar 12, 2026
b2004f1
feat(#261): Espresso Compass with taste-aware analysis
hessius Mar 13, 2026
cfdbfc7
feat(#281): temporary variable adjustments before running shots
hessius Mar 13, 2026
e66a309
feat: add Dial-In Guide wizard (#260)
hessius Mar 13, 2026
1fa3680
feat(a11y): comprehensive accessibility pass across all components (#…
hessius Mar 13, 2026
baa71da
fix: address all automated code review findings for v2.3.0
hessius Mar 13, 2026
d0750d8
fix(i18n): add 15 pre-existing missing keys to non-English locales
hessius Mar 13, 2026
a8420f3
fix: address code review findings for v2.3.0
hessius Mar 13, 2026
e2841d3
docs: add pre-release browser testing protocol
hessius Mar 13, 2026
c7b3567
fix: address v2.3.0 testing findings across UI, recommendations, and …
hessius Mar 16, 2026
95f4f84
merge: bring origin/main (v2.2.2) into version/2.3.0
hessius Mar 16, 2026
f8aab97
chore(deps): merge main (v2.2.2) + bump all dependencies for v2.3.0
hessius Mar 16, 2026
513f719
feat: code-splitting, animation variants, error boundaries, remove un…
hessius Mar 17, 2026
587d41a
fix(ci): align vitest@4.1.0 with @vitest/coverage-v8@4.1.0
hessius Mar 17, 2026
9b6b4bc
feat: replace Dial-In wizard with Espresso Compass + fix #175 remaini…
hessius Mar 17, 2026
18aa31d
fix: address second round of testing findings (#95, #258, #260, #281)
hessius Mar 17, 2026
68a43d5
fix(#281): variable editing panel — add missing endpoint + synthesize…
hessius Mar 18, 2026
9f83757
fix: address code review findings — bugs, race conditions, i18n
hessius Mar 18, 2026
7642731
fix(ui): improve spacing, overflow handling, and profile fallback (#1…
hessius Mar 18, 2026
90f5a63
fix(profiles): merge synthesized variables with explicit ones (#281)
hessius Mar 18, 2026
f411bf4
fix(i18n): complete Espresso Compass translation fixes (#260)
hessius Mar 18, 2026
e936694
fix: cross-cutting improvements + accessibility tests
hessius Mar 18, 2026
7705b16
feat(pour-over): persist coffee weight and brew ratio across sessions
hessius Mar 18, 2026
1914843
fix(i18n): replace 50+ hardcoded error strings with t() calls
hessius Mar 18, 2026
e911c33
fix(ui): use mt-4 for shot annotation card spacing
hessius Mar 19, 2026
adcbca7
feat(analysis): support stage exit trigger and limit edits via recomm…
hessius Mar 19, 2026
1680795
feat(recommendations): replace AI with structural profile comparison
hessius Mar 20, 2026
8f9b0d7
feat: ephemeral profile loading + fix variable panel bug (#281)
hessius Mar 20, 2026
4f4f7b2
fix: persist doseGrams and brewRatio in pour-over preferences
hessius Mar 20, 2026
1ee7576
feat: bulk delete profiles from machine
hessius Mar 20, 2026
55b20e8
fix: show variable adjust panel when navigating with initial profile
hessius Mar 20, 2026
fddaa85
docs: update Continuity auto-generated sections
hessius Mar 20, 2026
bd16196
fix: pre-select profile during preheat phase (#281)
hessius Mar 20, 2026
05e9b62
fix: disable watchtower in dev overlay to prevent image replacement
hessius Mar 20, 2026
c0d2af6
fix(profiles): clean up catalogue UI with image cache and profile thu…
hessius Mar 21, 2026
e9a05eb
fix(runShot): variable panel reliability, i18n, save-as-new toggle, p…
hessius Mar 21, 2026
656e5f5
fix(ui): improve recommendation dialog layout on mobile
hessius Mar 21, 2026
f4f5b72
fix(a11y): add aria-labels to back buttons and chart containers
hessius Mar 21, 2026
47a3e48
fix(pour-over): add doseGrams and brewRatio to Pydantic preferences m…
hessius Mar 21, 2026
98005bf
docs: update v2.3.0 testing checklist with accessibility and pour-ove…
hessius Mar 21, 2026
c0cefd2
fix(profiles): move export/delete buttons to edit mode in catalogue
hessius Mar 21, 2026
bce259f
fix(runShot): improve variable adjust panel and fix preheat subtitle
hessius Mar 21, 2026
2aa7afd
fix(variables): filter emoji info vars and exempt base vars from unus…
hessius Mar 21, 2026
9af1ba3
feat: profile image improvements — download, auto-scroll, no-text prompt
hessius Mar 21, 2026
d0e540b
fix: scroll to top on all intra-component view transitions
hessius Mar 21, 2026
1a57c72
fix(liveView): remove Power line from live shot chart
hessius Mar 21, 2026
617a119
fix(runShot): save-as-new shows correct name in live view and saves t…
hessius Mar 22, 2026
2afb82e
fix(docker): bump s6-overlay to 3.2.2.0 (3.2.0.x releases return 404)
hessius Mar 22, 2026
272bb6f
fix: preheat-only navigation and stale profile in control center
hessius Mar 23, 2026
085b860
fix(preheat): don't load profile before preheat to prevent auto-start
hessius Mar 25, 2026
07b2503
chore(release): bump version to 2.3.0-beta.2
hessius Mar 25, 2026
6179c9e
fix(ci): add security-events permission for SBOM and remove stale bra…
hessius Mar 25, 2026
08b2a7d
chore(release): bump version to 2.3.0
hessius Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ This project uses Continuity to track architectural decisions. You have access t
- **Known Topics:** none yet

## Current State
**Branch:** version/2.1.0
**Branch:** version/2.3.0

**Recent Commits:**
- `0f98171 fix(build): move aiAvailable declaration before canSubmit to fix TDZ error`
- `dbeca4e fix(docker): include recipe subdirectory contents in Docker build`
- `ca5f8ba fix: release readiness fixes for v2.1.0`
- `eaace10 chore(release): bump version to 2.1.0-beta.6`
- `2ef7e99 fix(lint): defer setState in timeout effect to satisfy react-hooks lint rule`
- `e2841d3 docs: add pre-release browser testing protocol`
- `a8420f3 fix: address code review findings for v2.3.0`
- `d0750d8 fix(i18n): add 15 pre-existing missing keys to non-English locales`
- `baa71da fix: address all automated code review findings for v2.3.0`
- `1fa3680 feat(a11y): comprehensive accessibility pass across all components (#186)`

**Working Tree:**
- M apps/mcp-server
- ?? apps/web/src/components/ShotHistoryView.tsx
- ?? v2.3.0-testing-checklist.md


## Engineering Guardrails
Expand Down Expand Up @@ -123,6 +124,6 @@ content="Description of the issue"

---

*Auto-generated by Continuity v2.3+ | Updated: 2026-03-09*
*Auto-generated by Continuity v2.3+ | Updated: 2026-03-16*

<!-- END CONTINUITY AUTO-GENERATED CONTENT -->
1 change: 1 addition & 0 deletions .github/CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ These are **non-negotiable**. Every PR, every push, every completion claim:
4. **All code review comments addressed.** Including suppressed/collapsed threads. Don't dismiss without clear justification.
5. **Tests pass locally before pushing.** Don't rely on CI as your first test run.
6. **Wide review on bug discovery.** When discovering a bug or potential issue, always do a wide review to look for the same or similar issues across the codebase. Bugs are often part of a pattern — fix the pattern, not just the instance.
7. **Browser testing before release.** Run the full browser testing protocol (`.github/skills/browser-testing.md`) against a live Docker container before any non-beta version bump.

## Testing

Expand Down
141 changes: 140 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,148 @@ MeticAI is an AI-powered controller for the Meticulous Espresso Machine. Stack:

## Skills

Detailed domain instructions are in `.github/skills/`: `workflow.md`, `testing.md`, `frontend.md`, `backend.md`, `release.md`, `conventions.md`.
Detailed domain instructions are in `.github/skills/`: `workflow.md`, `testing.md`, `frontend.md`, `backend.md`, `release.md`, `conventions.md`, `browser-testing.md`.

## Barista Persona (Profile Generation)

- **Naming:** Witty, pun-heavy, but clear (e.g., "Slow-Mo Blossom").
- **Output format:** Always include "Profile Created:", "Description:", "Preparation:", "Why This Works:", "Special Notes:".

<!-- AUTO-GENERATED BY CONTINUITY - DO NOT EDIT BELOW THIS LINE -->

# Project Memory (Auto-generated by Continuity)

This project uses Continuity to track architectural decisions. You have access to MCP tools that let you search, log, and reference past decisions.

## Project Context
- **Total Decisions:** 0
- **Known Topics:** none yet

## Current State
**Branch:** version/2.3.0

**Recent Commits:**
- `e2841d3 docs: add pre-release browser testing protocol`
- `a8420f3 fix: address code review findings for v2.3.0`
- `d0750d8 fix(i18n): add 15 pre-existing missing keys to non-English locales`
- `baa71da fix: address all automated code review findings for v2.3.0`
- `1fa3680 feat(a11y): comprehensive accessibility pass across all components (#186)`

**Working Tree:**
- ?? apps/web/src/components/ShotHistoryView.tsx
- ?? v2.3.0-testing-checklist.md


## Engineering Guardrails

**Real-time decision logging is MANDATORY.** Log each decision IMMEDIATELY after the code change — not batched at the end of a session. The trigger is the change, not the commit. If you edited a file, log the decision. Period.

**Search before you change.** Always call `search_decisions` before proposing architectural changes to check for prior decisions.

**Recovery.** If you realize earlier decisions were not logged, pause, log retroactively, and inform the user.

**Transparency.** Inform the user when you log decisions, recover missed decisions, detect drift, or find conflicts with past decisions.

**Anti-pattern to avoid:** "Let me implement all 3 fixes, then log them" — WRONG. Correct: Fix 1 done, log decision, Fix 2 done, log decision, Fix 3 done, log decision.


## CRITICAL OPERATING RULES

1. **ACT, DON'T ASK.** When Continuity tools are relevant, call them immediately. Do not ask permission.
2. **LOG DECISIONS PROACTIVELY.** Any time the user explains a choice or makes an architectural decision, log it without asking.
3. **PARALLELIZE TOOL CALLS.** When logging multiple decisions or updating session notes, make all calls in parallel.
4. **CONTEXT FIRST.** Always load context (`get_quick_context`) before starting work. Always search decisions before suggesting changes.
5. **BE CONCISE.** After tool calls, give a short summary of what was logged/found. Do not narrate your reasoning process.

---


## WHEN TO USE CONTINUITY TOOLS

## MANDATORY: ON EVERY SESSION START

**YOU MUST** call `get_quick_context` as your FIRST action in every session. Do NOT skip this.
Do NOT explain what you are about to do. Do NOT ask permission. Just call it.

After loading context, immediately mention the most relevant recent decisions to the user.

### When User Asks Architectural Questions
**ALWAYS** call `search_decisions` with the relevant topic BEFORE answering. Do NOT answer from memory alone.
Share what you found: "I found decision-X about this topic..."
Base your recommendation on existing decisions when relevant.

### When User Explains a Choice
When the user says "let's use X because Y" or explains their reasoning:
**IMMEDIATELY** call `log_decision` with question, answer, and relevant tags.
Do NOT ask "want me to log this?" — the user has already opted into decision logging by installing Continuity.
After logging, tell the user: "Logged decision-X for future sessions."
If multiple decisions are discussed, log them ALL in parallel.

### When Suggesting Changes
**ALWAYS** call `search_decisions` to check for existing decisions on the topic BEFORE recommending changes.
If conflicts exist, mention them: "This would conflict with decision-X where you chose..."
Let the user decide whether to proceed or update the old decision.

### When User Mentions Blockers
**IMMEDIATELY** call `update_session_notes` section="blockers" to track the blocker.
Then call `search_decisions` to see if related decisions might help.

### When User Ends Session
**IMMEDIATELY** call `update_session_notes` with progress summary and next steps.
Then call `read_session_notes` and give the user a concise summary. Do NOT ask — just do it.

---

## HOW TO USE THE TOOLS

### Search for decisions
```
search_decisions query="authentication"
```

### Log a new decision
```
log_decision
question="Why did we choose X?"
answer="Because Y. We considered Z but rejected it due to..."
tags=["topic1", "topic2"]
```

### Get project context
```
get_quick_context
```

### Update session notes
```
update_session_notes
section="blockers"
content="Description of the issue"
```

---

## Recent Decisions
*No decisions logged yet. Start logging architectural decisions!*

---

## BEHAVIOR EXAMPLES

**User:** "Should we use Redis or Memcached for caching?"
**You:** *[Immediately call search_decisions query="caching"]*
"Found decision-12 about caching strategy. Based on that, here's my recommendation..."

**User:** "Let's go with PostgreSQL because we need ACID transactions for the payment system."
**You:** *[Immediately call log_decision with question, answer, tags]*
"Logged as decision-45. Future sessions will know why we chose PostgreSQL."

**User:** "I'm thinking of switching to MongoDB."
**You:** *[Immediately call search_decisions query="database"]*
"Decision-12 chose PostgreSQL for ACID transactions. Switching to MongoDB would conflict. Want to proceed or keep PostgreSQL?"

---

*Auto-generated by Continuity v2.3+ | Updated: 2026-03-16*

<!-- END CONTINUITY AUTO-GENERATED CONTENT -->
152 changes: 152 additions & 0 deletions .github/skills/browser-testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Agent Skill: Pre-Release Browser Testing Protocol

This skill defines the manual browser testing protocol to run against a live Docker container before each release. Run this **after** all automated tests pass and **before** the final version bump.

## Prerequisites

1. Docker container running with the latest code:
```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml build --no-cache
docker rm -f meticai 2>/dev/null; docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
```
2. Container healthy: `docker exec meticai curl -sf http://localhost:3550/health`
3. Browser tool available (VS Code MCP browser, Playwright, or manual browser at `http://localhost:3550`)

## Test Protocol

Execute each section in order. Record PASS/FAIL for each item.

### 1. Start Screen

- [ ] Page loads without errors (check console)
- [ ] Version banner shows correct version (e.g., `2.3.0-beta.1`)
- [ ] Profile count displays correctly
- [ ] All navigation buttons visible: Generate, Catalogue, Run/Schedule, Dial-In Guide, Pour Over, Shot Analysis, Settings
- [ ] Light/dark mode toggle works and persists on reload
- [ ] MeticAI logo navigates to start screen

### 2. Profile Catalogue

- [ ] Opens and loads profiles with images
- [ ] Profile count matches start screen count
- [ ] Profile cards show name, author, date, description preview
- [ ] Download JSON and Delete buttons present on each card
- [ ] Filter by tags button present
- [ ] Manage machine profiles (sync) button present
- [ ] Clicking a profile opens detail view

### 3. Profile Detail

- [ ] Profile name, date, and image display correctly
- [ ] Edit profile button (pencil icon) present next to name
- [ ] "Shot History & Analysis" and "Run/Schedule" action buttons present
- [ ] Description, Preparation, Why This Works, Special Notes sections render with formatted content
- [ ] Notes section with "Add note" button
- [ ] Profile details sidebar: temperature, target weight, variables
- [ ] Profile image section: Upload and Generate buttons
- [ ] Export as Image/JSON buttons

### 4. Shot History & Analysis

- [ ] Loading screen with progress bar and percentage
- [ ] Shot list loads with profile-specific shots
- [ ] Each shot shows: profile name, date/time, duration, yield weight
- [ ] "Search for new shots" button works
- [ ] Last updated timestamp shown

### 5. Shot Detail

- [ ] Stats header: Duration, Yield, Temperature
- [ ] **Replay tab**: Extraction graph with Flow, Grav. Flow, Pressure, Weight series, stage overlays, tooltip on hover, playback controls
- [ ] **Compare tab**: Loads and allows shot comparison
- [ ] **Analyze tab**:
- Shot summary (weight, duration, max pressure, max flow)
- Shot vs Profile Target chart
- Stage-by-stage breakdown with targets, limits, and status
- "Fetch AI Analysis" button (if AI enabled)
- Export as Image button
- [ ] Star rating (1-5 stars) and notes section below tabs

### 6. Shot Analysis View (from start screen)

- [ ] "Recent" and "By Profile" tab toggle
- [ ] Recent shots list with profile names, dates, metrics, analysis icon
- [ ] By Profile view groups shots under profile headers
- [ ] Clicking a shot opens shot detail

### 7. Dial-In Guide (Wizard)

- [ ] **Step 1 (Coffee Details)**: Roast level buttons, origin input, process buttons, roast date, profile name
- [ ] **Step 2 (Select Profile)**: Machine profile list or manual name input, skip option
- [ ] **Step 3 (Preparation)**: Checklist (grind, weigh, distribute, tamp, flush), ready/skip buttons
- [ ] **Step 4 (Brew)**: Coffee cup icon, "Shot done" button
- [ ] **Step 5 (Taste)**: Taste Compass (2D, draggable), descriptor chips (8 positive + 8 negative), submit button enables when moved
- [ ] **Step 6 (Recommendations)**: AI-generated recommendations displayed (or rule-based fallback), "Adjust & try again" and "Finish" buttons
- [ ] **Step 7 (Finish)**: Returns to start screen with toast notification
- [ ] Progress bar updates at each step (14%, 29%, 43%, 57%, 71%, 86%, 100%)
- [ ] Back button navigates to previous step
- [ ] All text translated to selected language

### 8. Taste Compass (in Dial-In and Shot Analysis)

- [ ] SVG compass renders with 4 labeled axes (Sour/Bitter/Strong/Weak)
- [ ] Draggable dot responds to click/drag
- [ ] Color quadrants with gradient
- [ ] Descriptor chips: 8 positive (Sweet, Clean, Complex, Juicy, Smooth, Balanced, Floral, Fruity) and 8 negative (Astringent, Muddy, Flat, Chalky, Harsh, Watery, Burnt, Grassy)
- [ ] Selecting a descriptor activates it visually
- [ ] Reset button appears after first interaction

### 9. Run / Schedule

- [ ] Profile selector dropdown loads machine profiles
- [ ] Selected profile shows name, temperature, target weight
- [ ] Preheat toggle works
- [ ] Schedule toggle works
- [ ] "Run now" button enables when profile selected
- [ ] Variable adjustment panel appears when profile has adjustable variables (sliders/inputs)

### 10. Settings

- [ ] "About MeticAI" collapsible section
- [ ] Language selector with selected language highlighted
- [ ] Gemini API key field (shows configured/not configured status)
- [ ] "Enable AI features" toggle
- [ ] "Hide AI controls when unavailable" toggle
- [ ] Machine IP input field
- [ ] All labels translated to selected language

### 11. Accessibility

- [ ] Skip navigation links present ("Skip to main content", "Skip to navigation")
- [ ] Landmarks: `banner`, `main`, `navigation`
- [ ] ARIA labels on all icon-only buttons
- [ ] Live regions (aria-live) for wizard step changes, loading states
- [ ] Star rating buttons have descriptive labels ("1 star", "2 star", etc.)

### 12. Cross-Cutting Concerns

- [ ] No unhandled JavaScript errors in console (warnings OK)
- [ ] All pages load within 5 seconds (excluding shot history search)
- [ ] Navigation between all views works (no dead-end states)
- [ ] Back button behavior consistent (returns to previous view)
- [ ] Toast notifications appear for user actions (success/error)

## Recording Results

Create a markdown table with results:

```markdown
| # | Area | Status | Notes |
|---|------|--------|-------|
| 1 | Start Screen | PASS | |
| 2 | Profile Catalogue | PASS | |
| ... | ... | ... | ... |
```

Post the results as a comment on the version PR.

## When to Run

- **Required**: Before every version bump to a non-beta release (e.g., `2.3.0-rc.1` or `2.3.0`)
- **Recommended**: After significant feature additions on a beta branch
- **After**: All automated tests pass, CI green, Docker container rebuilt
1 change: 1 addition & 0 deletions .github/skills/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Before bumping to a release version:
- CI is green on the version branch
- All PR review comments addressed (including suppressed threads)
- No deferred tasks remain
- **Browser testing protocol passed** (see `.github/skills/browser-testing.md`)

## 2. Version Bump

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ on:
pull_request:
branches:
- main
- version/2.0.0
paths:
- 'apps/**'
- 'docker/**'
Expand All @@ -39,6 +38,7 @@ jobs:
permissions:
contents: read
packages: write
security-events: write

steps:
- name: Checkout repository
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
env:
GEMINI_API_KEY: test_key_for_ci
run: |
pytest test_main.py test_logging.py -v \
pytest test_main.py test_logging.py test_taste_compass.py test_recommendations.py -v \
--cov=main --cov=logging_config --cov=config \
--cov=prompt_builder --cov=api --cov=services \
--cov=utils --cov=models \
Expand Down
Loading
Loading