diff --git a/.github/agents/release-manager.agent.md b/.github/agents/release-manager.agent.md index 2a63ae4..240d635 100644 --- a/.github/agents/release-manager.agent.md +++ b/.github/agents/release-manager.agent.md @@ -13,6 +13,7 @@ You are the release manager for **MedAssist-ng**. Your job is to guide code from ## Critical Safety Rules - **NEVER release, tag, push, or create PRs without explicit user confirmation at each step.** Always present your plan and wait for approval. +- **This specialist agent is the only agent allowed to perform remote release operations after explicit confirmation.** - **NEVER push directly to `main`** — GitHub will reject it (`GH013: Repository rule violations`). All changes go through Pull Requests. - **NEVER skip CI checks.** Wait for all status checks to pass before merging. - **Testing ownership belongs to `@testing-manager`**. Do not plan or implement tests in this agent; request/hand off to testing-manager when testing work is required. @@ -48,12 +49,11 @@ This repository intentionally uses only two operational agents for CI/CD handoff - Never use `gh` commands that can open an interactive pager and block execution (requiring `q`). - Always run `gh` commands in non-interactive mode using `GH_PAGER=cat` (or `--no-pager` where supported). -- Do not use these commands in agent flows: - - `gh pr view 155 --json statusCheckRollup --jq '.statusCheckRollup[] | {name:.name,conclusion:.conclusion,detailsUrl:.detailsUrl,workflowName:.workflowName}'` - - `SHA=$(gh pr view 155 --json headRefOid --jq .headRefOid) && gh api repos/DanielVolz/medassist-ng/commits/$SHA/check-runs --jq '.check_runs[] | {name,conclusion,details_url,html_url,app:.app.name}'` -- Use safe variants instead: +- Avoid hardcoded PR/repo examples in instructions; always use parameterized placeholders. +- Use safe command patterns: - `GH_PAGER=cat gh pr view --json statusCheckRollup --jq ''` - - `GH_PAGER=cat gh api repos///commits//check-runs --jq ''` + - `SHA=$(GH_PAGER=cat gh pr view --json headRefOid --jq .headRefOid)` + - `GH_PAGER=cat gh api repos///commits/$SHA/check-runs --jq ''` --- diff --git a/.github/agents/testing-manager.agent.md b/.github/agents/testing-manager.agent.md index e086c4c..0ea8227 100644 --- a/.github/agents/testing-manager.agent.md +++ b/.github/agents/testing-manager.agent.md @@ -15,6 +15,8 @@ You are the testing manager for **MedAssist-ng**. Your job is to ensure every fe - **Tests are mandatory**: Every new feature and every bug fix MUST have corresponding tests. - **Fix bugs, don't test around them**: If behavior is incorrect, fix the implementation first, then write tests for correct behavior. - **Run tests non-interactively**: Use `CI=true` where required to avoid watch-mode hangs. +- **Playwright must disable auto-open reports**: Always prefix Playwright runs with `PLAYWRIGHT_HTML_OPEN=never`. +- **Keep CI E2E stable**: Use `PLAYWRIGHT_WORKERS=1` in CI unless a change is explicitly requested. - **Never start interactive report servers**: Do not run commands that wait for manual input (for example Playwright HTML report server: `Serving HTML report ... Press Ctrl+C to quit`). Always use finite, non-interactive commands and reporters. - **No remote git operations**: Do not push, merge, create PRs, tags, or releases. Hand over to `@release-manager` when ready. - **Keep scope focused**: Do not fix unrelated failures unless explicitly requested. @@ -66,8 +68,9 @@ cd frontend && npm run build ### Playwright E2E ```bash -cd frontend && npm run test:e2e -cd frontend && npm run test:e2e -- --project=chromium +cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e +cd frontend && PLAYWRIGHT_HTML_OPEN=never PLAYWRIGHT_WORKERS=4 npm run test:e2e:local +cd frontend && PLAYWRIGHT_HTML_OPEN=never npm run test:e2e -- --project=chromium # Never use interactive UI/headed/report-server commands in agent runs. # Do not use: npm run test:e2e:ui, npm run test:e2e:headed, npx playwright show-report ``` diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index a2ffa40..a53a10f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,77 +1,13 @@ -# MedAssist-ng - AI Coding Instructions +# MedAssist-ng - Copilot Entry Point -## Purpose +Use `AGENTS.md` as the single source of truth for all governance, workflow, and skill rules. -Use `AGENTS.md` as the canonical governance source. Read the referenced skill files before starting any task. +## Required Startup Steps -## Project Orientation (Read First) +1. Read `AGENTS.md` first. +2. Identify triggered skills from `AGENTS.md` and read each referenced `SKILL.md` before making changes. +3. Follow delegation boundaries exactly (`@testing-manager` for testing, `@release-manager` for release orchestration). -- **Product**: MedAssist-ng is a medication planner with stock tracking, reminders (email/push), refill history, and schedule sharing. -- **Tech stack**: React + TypeScript + Vite (`frontend/`), Fastify + TypeScript + Drizzle + SQLite (`backend/`). -- **Request path**: Frontend uses `/api/*` only; backend route handlers live in `backend/src/routes/`. -- **Primary backend modules**: - - Auth/SSO: `backend/src/routes/auth.ts`, `backend/src/routes/oidc.ts`, `backend/src/plugins/auth.ts` - - Medications/data: `backend/src/routes/medications.ts`, `backend/src/db/schema.ts` - - Reminders: `backend/src/services/reminder-scheduler.ts`, `backend/src/routes/planner.ts`, `backend/src/routes/settings.ts` -- **Primary frontend modules**: - - Pages: `frontend/src/pages/` - - Shared app state: `frontend/src/context/AppContext.tsx` - - Domain hooks: `frontend/src/hooks/` - - Translations: `frontend/src/i18n/en.json`, `frontend/src/i18n/de.json` +## Scope -Use this orientation for quick navigation before applying the rules below. - -## Always-On Rules - -- English only for project artifacts. -- **NEVER run remote git commands** — no `git push`, no `gh pr create/merge`, no `gh release`, no `git tag`. Prepare locally, then hand off to `@release-manager`. -- Testing work belongs to `@testing-manager`. -- PR/release/CI orchestration belongs to `@release-manager`. -- Keep changes local, focused, and consistent with existing UI/API patterns. -- **Hard PR scope + size rule**: one cohesive objective per PR; if scope drifts or diff becomes large (target <= 500 changed lines, hard split at ~800+), split into logical follow-up PRs instead of bundling. -- Remove obsolete code when re-implementing — never leave dead code behind. -- **Document behavioral discoveries**: When you discover or clarify how a feature works (e.g., what triggers notifications, how thresholds interact, which code paths exist), **always** add or update the relevant section in `doku/APP_BEHAVIOR.md`. This is mandatory — do not rely on conversation context alone. - -## MedAssist Essentials - -- Frontend calls backend through `/api/*`. -- DB changes must stay backward-compatible (schema default + alter migration + null-safe reads). - ---- - -## Skills (MANDATORY — read before every task) - -Before starting any task, identify which skills apply and **read their full SKILL.md file** for detailed rules. - -| Skill | Trigger | File | -|---|---|---| -| **Architecture Guard** | API endpoints, frontend API calls, routing, code placement | `.github/skills/medassist-architecture-guard/SKILL.md` | -| **DB Compatibility** | Persisted data, schema changes, migrations | `.github/skills/medassist-db-compat-check/SKILL.md` | -| **i18n Enforcer** ⚠️ | Any user-facing text in frontend or backend | `.github/skills/medassist-i18n-enforcer/SKILL.md` | -| **UI Consistency** | UI flows, modals, buttons, forms, settings | `.github/skills/medassist-ui-consistency/SKILL.md` | -| **Frontend Polish** | Visual quality improvements | `.github/skills/medassist-frontend-polish/SKILL.md` | -| **Security Sanity** | Backend routes, auth, file handling, external input | `.github/skills/medassist-security-sanity/SKILL.md` | -| **Observability Guard** | Services, schedulers, startup, failure handling | `.github/skills/medassist-observability-guard/SKILL.md` | -| **Config Change Guard** | `.env`, Docker, Vite proxy, runtime defaults | `.github/skills/medassist-config-change-guard/SKILL.md` | -| **Doc Sync Guard** | Behavior changes, setup, env vars, workflows | `.github/skills/medassist-doc-sync-guard/SKILL.md` | -| **Testing Handoff** | Writing/running tests, CI test failures | `.github/skills/medassist-testing-handoff/SKILL.md` | -| **Release Handoff** | Branch push, PR, merge, tagging, release | `.github/skills/medassist-release-handoff/SKILL.md` | -| **Skill Quality Review** | Creating/modifying skills | `.github/skills/medassist-skill-quality-review/SKILL.md` | - -### Non-negotiable parity rules (always apply) - -1. **Desktop + Mobile Parity**: Medication edit has two paths — `MedicationsPage.tsx` (desktop) and `MobileEditModal` (mobile). **Always update BOTH**. -2. **Notification Dual Code Paths**: Notifications have two code paths — `backend/src/services/reminder-scheduler.ts` (scheduler) and `backend/src/routes/planner.ts` (manual). **Always update BOTH**. - ---- - -## Delegation - -- **Testing handoff → `@testing-manager`**: test planning, writing, execution, CI test triage. -- **Release handoff → `@release-manager`**: PR/release orchestration, merge flow, workflow monitoring. - -## Key References - -- Canonical governance: `AGENTS.md` -- Skill files: `.github/skills/*/SKILL.md` -- Specialist agents: `.github/agents/testing-manager.agent.md`, `.github/agents/release-manager.agent.md` +This file intentionally stays minimal to prevent duplicated or conflicting instructions. diff --git a/.github/skills/README.md b/.github/skills/README.md index 2759d15..1a78604 100644 --- a/.github/skills/README.md +++ b/.github/skills/README.md @@ -13,7 +13,7 @@ Use one governance source to avoid duplicated or conflicting policy text. ## Skills -- `medassist-karpathy-core` — enforce assumption clarity, simplicity, surgical diffs, and verifiable execution. +- `medassist-karpathy-core` — enforce think-before-coding, simplicity-first changes, surgical diffs, and goal-driven verification. - `medassist-architecture-guard` — enforce frontend/backend boundary and `/api/*` data-flow conventions. - `medassist-db-compat-check` — enforce backward-compatible SQLite/Drizzle schema changes. - `medassist-i18n-enforcer` — enforce translation-key-only UI copy with EN/DE parity. diff --git a/.github/skills/medassist-karpathy-core/SKILL.md b/.github/skills/medassist-karpathy-core/SKILL.md index e69de29..0fc992c 100644 --- a/.github/skills/medassist-karpathy-core/SKILL.md +++ b/.github/skills/medassist-karpathy-core/SKILL.md @@ -0,0 +1,69 @@ +--- +name: medassist-karpathy-core +description: Apply assumption clarity, simplicity-first implementation, surgical diffs, and goal-driven verification for non-trivial coding tasks. +--- + +# Skill Instructions + +Use this skill as an execution style layer for implementation tasks where overengineering, broad refactors, or unclear assumptions are likely. + +## Use When + +- The request is ambiguous and assumptions must be made explicit. +- The change can easily balloon in scope. +- A bug fix or feature needs explicit success criteria and verification. +- You need to keep diffs minimal and directly tied to the request. + +## Do Not Use When + +- The task is trivial and can be completed safely without extra process overhead. +- The task is only about ownership routing (use `medassist-testing-handoff` / `medassist-release-handoff`). +- The task is only about domain guardrails already covered by specialized skills (architecture, DB, i18n, UI, security, config, observability). + +## Core Principles + +### 1. Think Before Coding + +- Do not assume silently. +- State assumptions explicitly. +- If multiple interpretations exist, present them instead of picking one invisibly. +- If uncertain or blocked by ambiguity, stop and ask. +- If a simpler approach exists, call it out. + +### 2. Simplicity First + +- Implement the minimum code required to solve the asked problem. +- Do not add speculative features, abstractions, or configurability. +- Avoid defensive handling for impossible scenarios. +- If the solution feels overcomplicated, simplify before finalizing. + +### 3. Surgical Changes + +- Touch only lines required for the request. +- Do not refactor unrelated areas. +- Match existing local style and patterns. +- Remove only unused code introduced by your own change. +- If unrelated dead code is discovered, mention it but do not remove it unless requested. + +### 4. Goal-Driven Execution + +- Translate requests into verifiable outcomes before implementation. +- For multi-step tasks, define short steps with checks. +- Verify the requested behavior explicitly before declaring done. + +Example execution frame: + +```text +1. [Step] -> verify: [check] +2. [Step] -> verify: [check] +3. [Step] -> verify: [check] +``` + +## Response Format + +When this skill is used, report briefly: + +- Assumptions made (or clarifications requested) +- Why the chosen approach is the simplest viable one +- What was changed (and what was intentionally not changed) +- Verification performed and result diff --git a/README.md b/README.md index f1e8419..659e1cb 100644 --- a/README.md +++ b/README.md @@ -250,7 +250,9 @@ Generate secrets with: `openssl rand -hex 32` MedAssist uses [Shoutrrr](https://containrrr.dev/shoutrrr/) for push notifications, supporting many services with a single URL format. -**Supported services:** ntfy, Pushover, Gotify, Discord, Telegram, Slack, Matrix, and [many more](https://containrrr.dev/shoutrrr/v0.8/services/overview/). +**Implemented URL schemes in MedAssist:** `ntfy://`, `discord://`, `pushover://`, `gotify://`, `telegram://`, plus direct `https://` webhooks. + +This covers common providers like ntfy, Discord, Pushover, Gotify, Telegram, Slack webhooks, and many others via webhook URLs. Configure push notifications in Settings → Push, or set defaults via environment variables: @@ -288,6 +290,7 @@ Get your keys at [pushover.net](https://pushover.net/): **Gotify** (self-hosted): ``` gotify://your-server.com/TOKEN +gotify://your-server.com:443/path/to/gotify/TOKEN?priority=1 ``` **Discord**: @@ -298,6 +301,7 @@ discord://TOKEN@WEBHOOK_ID **Telegram**: ``` telegram://TOKEN@telegram?chats=CHAT_ID +telegram://TOKEN@telegram?chats=@your_channel,-1001234567890 ``` For all services and options, see the [Shoutrrr documentation](https://containrrr.dev/shoutrrr/v0.8/services/overview/). @@ -311,6 +315,17 @@ docker compose -f docker-compose.dev.yml up - Frontend: `http://localhost:5173` (hot reload) - Backend: `http://localhost:3000` +Playwright E2E recommendations: + +```bash +cd frontend +npm run test:e2e:local # local run with PLAYWRIGHT_WORKERS=4 +npm run test:e2e:all:local # local all-browser run with PLAYWRIGHT_WORKERS=4 +``` + +- CI stays at `PLAYWRIGHT_WORKERS=1` for stability. +- Data-heavy specs remain sequential via the `chromium-data` project config. + # Acknowledgements This project was inspired by [MedAssist](https://github.com/njic/medassist) by njic.