Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
bfde7c5
feat(machine): add MachineService abstraction layer (#252)
hessius Mar 9, 2026
cb9368f
perf: lazy-load canvas-confetti (#188)
hessius Mar 9, 2026
73028fe
feat(server): add machine auto-detect via mDNS/zeroconf (#216)
hessius Mar 9, 2026
c7582b2
feat(profiles): add profile catalogue management view (#192 #182)
hessius Mar 9, 2026
c5f6ad3
feat(shots): add shot annotation system (#179)
hessius Mar 9, 2026
793e2da
feat(history): add profile notes with markdown editor (#225)
hessius Mar 9, 2026
7bd0f06
feat(settings): add AI summary controls (#234)
hessius Mar 9, 2026
466980a
Update apps/web/src/hooks/use-mobile.ts
hessius Mar 9, 2026
2d0f7ba
Update apps/web/src/hooks/useWebSocket.ts
hessius Mar 9, 2026
89c3612
Update apps/server/services/machine_discovery_service.py
hessius Mar 9, 2026
6d892b6
Update apps/server/requirements.txt
hessius Mar 9, 2026
fd0d7c4
Update apps/web/src/components/ProfileBreakdown.tsx
hessius Mar 9, 2026
c4e4e00
Update apps/web/src/components/ProfileBreakdown.tsx
hessius Mar 9, 2026
d710bff
Fix getServerUrl awaiting, render-phase setState, atomic_write_json P…
Copilot Mar 9, 2026
7c40138
feat(annotations): add star rating, delete endpoint, and shot list in…
hessius Mar 9, 2026
c1d7815
feat(profile-edit): add profile editing (#257)
hessius Mar 9, 2026
2383ad4
feat(profile-catalogue): add delete dialog, orphan detection, restore…
hessius Mar 9, 2026
968cb41
feat(sync): implement Profile Sync system (#182)
hessius Mar 9, 2026
d5c7576
feat(shots): add Shot Analysis view + lint fixes (#259)
hessius Mar 9, 2026
434715c
fix: address remaining PR review comments
hessius Mar 10, 2026
094220f
chore(deps): bump safe dependencies
hessius Mar 10, 2026
a7c36bf
chore(deps): bump typescript ~5.7.2 → ~5.9.3
hessius Mar 10, 2026
8e313ba
chore(deps): bump marked ^15.0.7 → ^17.0.4
hessius Mar 10, 2026
22aeb66
chore(deps): bump @hookform/resolvers ^4.1.3 → ^5.2.2
hessius Mar 10, 2026
9222bf9
chore(deps): bump recharts ^2.15.1 → ^3.8.0
hessius Mar 10, 2026
2447816
chore(deps): bump zod ^3.25.76 → ^4.3.6
hessius Mar 10, 2026
0b577c2
chore(release): bump version to 2.2.0-beta.1
hessius Mar 10, 2026
c2de599
fix(i18n): add missing navigation.shotAnalysis and navigation.pourOve…
hessius Mar 10, 2026
c2293e4
fix(api): expand profile responses with full stages/variables data
hessius Mar 10, 2026
d30449d
fix(web): stop notes toast spamming on every keystroke
hessius Mar 10, 2026
dc0aa34
fix(validation): enforce STRICT level and add unused variable check t…
hessius Mar 10, 2026
8a7ab69
fix(i18n): add missing settings translations and fix machine detect 405
hessius Mar 10, 2026
8132a87
fix(ui): target overlay, shot navigation, and analysis caching
hessius Mar 10, 2026
f6b5ee3
refactor(ui): consolidate profile catalogues, remove unused AI settings
hessius Mar 10, 2026
ff83af8
feat: implement #234 AI description controls and auto-sync
hessius Mar 10, 2026
c289bff
fix(i18n): translate ~35 shotHistory keys in all non-English locales
hessius Mar 10, 2026
7d996fa
chore(release): v2.2.0-beta.2 — fix review items, bump deps, harden code
hessius Mar 11, 2026
2e38870
test: add backend tests for history notes and machine detect endpoints
hessius Mar 11, 2026
e401ce6
fix: address all 12 open PR #262 review comments
hessius Mar 11, 2026
df0dd4b
docs(skills): add release & conventions skills, update workflow & tes…
hessius Mar 11, 2026
d85461a
feat: restructure agent setup with conventions, extensions, and DRY m…
hessius Mar 11, 2026
ae64295
fix: address all 6 PR #282 review comments + add wide-review convention
hessius Mar 11, 2026
3cc71d7
chore: remove stale planning docs accidentally committed
hessius Mar 11, 2026
8bbafde
fix: address round 2 review + comprehensive self-review findings
hessius Mar 11, 2026
7f14691
fix: standardize pytest -x -q flags and fix i18n section name in docs
hessius Mar 11, 2026
57fe90e
Merge feat/agent-setup-v2: agent setup restructure with conventions, …
hessius Mar 11, 2026
691f86f
feat: profile editing UX, validation fixes, and i18n improvements
hessius Mar 12, 2026
c1c9067
test(e2e): fix strict mode violations in app and history tests
hessius Mar 12, 2026
b9b0f82
chore(release): bump version to 2.2.0-beta.3
hessius Mar 12, 2026
b3fac21
fix: profile editing, split edit buttons, auto-sync background, env d…
hessius Mar 12, 2026
6e2c8ec
fix: persist auto-sync settings server-side and stay on profile after…
hessius Mar 12, 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
145 changes: 145 additions & 0 deletions .github/CONVENTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# MeticAI Project Conventions

> **This is the single source of truth for all project rules and conventions.**
> All agent configuration files (CLAUDE.md, AGENTS.md, GEMINI.md, copilot-instructions.md) reference this document.
> When in doubt, this file wins.

---

## Versioning

- The root `VERSION` file and `apps/web/package.json` version **must always be bumped together**.
- Changing `VERSION` triggers the auto-release workflow (`.github/workflows/auto-release.yml`).
- Version format: `MAJOR.MINOR.PATCH` with optional `-beta.N` or `-rc.N` suffixes.
- Release progression: `beta.1` → `beta.N` → `rc.1` → release (remove suffix).

## Branch Naming

| Purpose | Pattern | Example |
|---------|---------|---------|
| Milestone work | `version/X.Y.Z` | `version/2.2.0` |
| Feature branch | `feat/<name>` | `feat/temp-variables` |
| Website updates | `website/<name>` | `website/v2.2-redesign` |
| Bugfix | `fix/<name>` | `fix/cache-overflow` |
| Pages deployment | `pages` | `pages` (protected) |

- Feature branches are created from their parent milestone branch, not from `main`.
- The `pages` branch is completely separate — it contains only static website files, not based on `main`.

## Quality Gates

These are **non-negotiable**. Every PR, every push, every completion claim:

1. **CI must be completely green.** The Test Suite has 6 jobs (Web Tests, Server Tests, Code Quality, Pester, Web E2E, Docker Build Test) plus a separate Build and Publish workflow. All must pass.
2. **Zero tech debt.** Address all issues immediately. Never defer tasks to "later".
3. **No deferred tasks.** If a task is in scope, it gets done now — not added to a backlog.
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.

## Testing

### Backend (Python)
```bash
cd apps/server && TEST_MODE=true .venv/bin/python -m pytest test_main.py -x -q
```
- Currently 750+ tests. New code must include tests in `test_main.py`.
- Test both success and failure/edge-case paths.

### Frontend (TypeScript/React)
```bash
cd apps/web && bun run test:run
```
- Currently 277+ tests.
- Lint must be clean: `bun run lint` (0 errors; warnings OK per eslint v7 migration issue #256).
- Build must succeed: `bun run build`.

### Full Local Gate (run before pushing)
```bash
cd apps/server && TEST_MODE=true .venv/bin/python -m pytest test_main.py -x -q && \
cd ../web && bun run lint && bun run test:run && bun run build
```

## Commits

- **Format:** [Conventional Commits](https://www.conventionalcommits.org/) — `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`, `ci:`.
- **Trailer:** Always include `Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>`.
- **Scope (optional):** Use parenthetical scope for clarity — `fix(build):`, `feat(profiles):`.
- **Message:** Focus on *why*, not *what*. The diff shows what changed.

## Pull Requests

- Every PR must include: **Summary**, **How to Test**, and **Assumptions/Open Questions**.
- Update the PR description after significant changes (new commits, scope changes).
- Post a PR comment summarizing changes for substantial multi-file updates.
- Reference related issues with `Closes #N` or `Part of #N`.

## Internationalization (i18n)

- **All user-facing strings** must use the `t()` function from `react-i18next`.
- **All 6 locales** must be updated: `en`, `sv`, `de`, `es`, `fr`, `it`.
- Translation files: `apps/web/public/locales/{locale}/translation.json`.
- English is the source locale; other locales should have equivalent keys.

## Dependencies

### Frontend
- Use `bun add <package>` (never `npm install`).
- Always commit `bun.lock` alongside `package.json` changes.
- Bun version is pinned at **1.3.10** in both `docker/Dockerfile.unified` and CI workflows.
- Import from `lucide-react` public paths only (never private `dist` paths).

### Backend
- Pin versions in `apps/server/requirements.txt`.
- Rebuild the container after dependency changes.

## Code Style

### Python (apps/server/)
- PEP 8 strict. Extensive type hints. Google-style docstrings.
- Functions: focused and single-purpose.
- Concurrency: `threading.Lock` for synchronous file I/O, `asyncio.Lock` for async operations.
- Lazy lock creation (`_get_lock()` pattern) to avoid "attached to different loop" errors in tests.

### TypeScript/React (apps/web/)
- Functional components with hooks only. No class components.
- ESLint compliance (react-hooks rules). 5 strict v7 rules downgraded to warn (issue #256).
- Extend shadcn/ui components in `apps/web/src/components/ui/`; don't replace them.
- Mobile-first responsive design.

## Architecture Patterns

- **Dual route registration:** Both `/endpoint` and `/api/endpoint` are registered for every route. This is intentional to support clients that include or omit the `/api` prefix. Not a defect.
- **Unified container:** Single Docker container managed by s6-overlay. Port 3550 is the only exposed port (nginx proxy).
- **Settings hot-reload:** Changing `METICULOUS_IP` or `GEMINI_API_KEY` triggers `s6-svc -r` (service restart, not container restart).
- **Cache bounding:** In-memory caches must be bounded (e.g., 50 entries max). On insert: purge expired, then clear all if still over limit.
- **Safe parsing:** Use helper functions (e.g., `_safe_float()`) for user-provided numeric values. Never trust raw input.

## Release Process

1. Work on `version/X.Y.Z` branch with beta suffixes.
2. Run full test suite locally. Push. Wait for CI green.
3. Bump `VERSION` and `apps/web/package.json` to final version (remove `-beta.N`).
4. Merge `version/X.Y.Z` into `main` via PR.
5. Auto-release workflow creates the GitHub release and Docker image.
6. Update `pages` branch with release notes (via separate PR).

## Domain: Espresso Profiling

- **Barista Persona:** Profile names should be witty, pun-heavy, but clear (e.g., "Slow-Mo Blossom").
- **Profile Generation Output:** Always include "Profile Created:", "Description:", "Preparation:", "Why This Works:", and "Special Notes:".
- **Reference:** See `PROFILING_AXIOMS.md` for extraction principles, stage-based profiling, and exit trigger rules.
- **Profile Variables:** Two types — INFO (`info_` prefix, display-only, emoji names) and ADJUSTABLE (no prefix, user-modifiable types: pressure/flow/weight/power/time).
- **Temporary Profiles:** Managed via `temp_profile_service.py` — create_and_load → cleanup/force_cleanup lifecycle.

## CI Structure

- **Test Suite workflow:** 6 jobs — Web Tests, Server Tests, Code Quality, Pester, Web E2E, Docker Build Test.
- **Build and Publish workflow:** Separate, runs on merge to main.
- **Bun setup in CI:** Uses 3-attempt retry pattern to handle transient download failures.
- **Triggers:** Test Suite runs on PRs to `main`. Build and Publish on push to `main`.

---

*Last updated: 2026-03-11 | Maintained by the MeticAI team and AI agents*
*To add a new convention, use the `learn_convention` extension tool or edit this file directly.*
171 changes: 13 additions & 158 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,167 +1,22 @@
# MeticAI — Global Agent Context
# MeticAI — Agent Instructions

## 1. Project Overview
MeticAI is an AI-powered controller for the Meticulous Espresso Machine.
- **Stack:** Python 3.13 (FastAPI), React + TypeScript (Vite/Bun), Google Gemini Python SDK, Docker + s6-overlay.
- **Repository:** https://github.com/hessius/MeticAI
- **Version File:** `VERSION` (changing this triggers the auto-release workflow).
MeticAI is an AI-powered controller for the Meticulous Espresso Machine. Stack: Python 3.13 (FastAPI), React + TypeScript (Vite/Bun), Google Gemini Python SDK, Docker + s6-overlay. Repository: https://github.com/hessius/MeticAI. The `VERSION` file triggers the auto-release workflow.

## 2. Core Architecture
- **Unified Container:** Everything runs in a single container (`meticai`) managed by s6-overlay. Port 3550 is the only exposed port (nginx proxy).
- **Settings Hot-Reload:** Changing `METICULOUS_IP` or `GEMINI_API_KEY` restarts internal services (`s6-svc -r`) without a full container restart.
- **Environment:** Requires `.env` with `GEMINI_API_KEY` and `METICULOUS_IP`.

## 3. Agent Skills & Progressive Disclosure
Detailed instructions are progressively disclosed. Load these skills from `.github/skills/` when needed:
- **Workflow & Safety:** Invoke the `workflow.md` skill for session execution phases, branch naming, and PR rules.
- **Testing & Building:** Invoke the `testing.md` skill for Docker commands, Pytest, and Playwright suites.
- **Domain Standards:** Invoke `frontend.md` or `backend.md` skills when working in `apps/web/` or `apps/server/`.

## 4. MCP Tools & Continuity
You are equipped with MCP tools for state and architecture management. You must use them:
- **Mandatory:** Always call `get_quick_context` as your first action in every session.
- **Proactive Logging:** Call `log_decision` immediately when architectural choices are discussed or made.
- **Search First:** Always call `search_decisions` before proposing changes.
- **Session End:** Call `update_session_notes` with progress and read them back.

## 5. 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:", and "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.1.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`

**Working Tree:**
- M apps/mcp-server


## 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.
## Core Architecture

---


## 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
- **Unified Container:** Single container (`meticai`) via s6-overlay. Port 3550 exposed (nginx proxy).
- **Settings Hot-Reload:** Changing `METICULOUS_IP` or `GEMINI_API_KEY` restarts services (`s6-svc -r`) without full container restart.
- **Environment:** Requires `.env` with `GEMINI_API_KEY` and `METICULOUS_IP`.

**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..."
## Conventions

**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."
**All project conventions** (versioning, quality gates, testing, commits, i18n, release process) are defined in `.github/CONVENTIONS.md`. Read it before starting any work.

**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?"
## Skills

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

*Auto-generated by Continuity v2.3+ | Updated: 2026-03-09*
## Barista Persona (Profile Generation)

<!-- END CONTINUITY AUTO-GENERATED CONTENT -->
- **Naming:** Witty, pun-heavy, but clear (e.g., "Slow-Mo Blossom").
- **Output format:** Always include "Profile Created:", "Description:", "Preparation:", "Why This Works:", "Special Notes:".
Loading
Loading