diff --git a/.agents/skills/pull-request/SKILL.md b/.agents/skills/pull-request/SKILL.md new file mode 100644 index 000000000..7ee61b40e --- /dev/null +++ b/.agents/skills/pull-request/SKILL.md @@ -0,0 +1,166 @@ +--- +name: pull-request +description: Standardize pull request creation. Validates branch name and commits against Conventional Commits spec, audits diff size (flag if >500 lines excluding generated files), proposes split if too large, then creates a PR with structured description (problem, changes, testing checklist). Triggers when user says "create PR", "open a pull request", "make a PR", "/pull-request", or asks to submit work for review. +argument-hint: "[target-branch]" +--- + +# /pull-request - Standardized PR Creation + +## Defaults + +- Default target branch: `dev`, unless the user specifies a target branch or repository context clearly indicates a different default. +- Do not force-push, rebase, amend, or rename branches unless the user explicitly asks. +- Never create a PR until branch name, commit compliance, and diff size audit have been presented and the user confirms continuing. + +## Step 1: Validate Branch Name + +Run: + +```bash +git rev-parse --abbrev-ref HEAD +``` + +Branch names must match: + +```text +/ +``` + +Allowed types: `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `perf`, `ci`, `build`. + +Examples: `fix/delete-study-fk`, `feat/date-question`, `refactor/fitbit-tab`. + +If the current branch does not match, stop and propose: + +```text +Branch name "" doesn't follow conventions. +Suggested: / +Rename with: git branch -m +``` + +Wait for the user to rename or explicitly confirm continuing. + +## Step 2: Audit Commits + +Run: + +```bash +git log ..HEAD --oneline +``` + +Each commit subject must match: + +```text +[optional scope]: +``` + +Allowed types: `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `perf`, `ci`, `build`, `revert`. + +Rules: + +- Subject line is 72 characters or fewer. +- Description uses imperative mood, for example `add`, not `added`. +- No trailing period. +- Breaking change uses `!` after type/scope or a `BREAKING CHANGE:` footer. + +For every non-compliant commit, present all proposed rewrites at once: + +```text +Commit: "some bad message" +Proposed: "fix(auth): handle expired token on login" +Reword with: git rebase -i +``` + +Wait for the user to fix or explicitly confirm continuing. + +## Step 3: Audit Diff Size + +Run: + +```bash +git diff ...HEAD --stat +``` + +Count changed lines excluding generated and translation files: + +- `*.g.dart` +- `*.freezed.dart` +- `*/l10n/*.dart` +- `*/generated/*` +- `*.g.ts` +- `*.lock` +- `pubspec.lock` + +If total non-excluded changed lines exceed 500, analyze the diff and propose an independently mergeable split by feature area, layer, or dependency order: + +```text +PR is too large: ~ lines (excluding generated files). + +Proposed split: + PR 1 - /: (~ lines) + Files: + PR 2 - /: (~ lines) + Files: + +Proceed with single PR anyway? Or split? +``` + +Wait for the user decision. + +## Step 4: Collect PR Info + +Run in parallel when possible: + +```bash +git diff ...HEAD --stat +git log ..HEAD --format="%s%n%b" +``` + +Derive: + +- Problem: what was broken or missing, using commits and diff context. +- Changes: grouped bullet list by area. +- Testing: checklist of verification steps, including commands already run. + +## Step 5: Create the PR + +Push the branch: + +```bash +git push -u origin HEAD +``` + +Create the PR with GitHub CLI: + +```bash +gh pr create \ + --title "[scope]: " \ + --base \ + --body "$(cat <<'EOF' +## Problem + + +## Changes +- +- + +## Testing +- [ ] +- [ ] +- [ ] No regressions in +EOF +)" +``` + +PR title rules: + +- Format: `[optional scope]: `. +- Maximum 72 characters. +- Imperative mood. +- No trailing period. + +If `gh` is not authenticated, stop and tell the user to run: + +```bash +gh auth login +``` diff --git a/.claude/commands/pull-request.md b/.claude/commands/pull-request.md new file mode 120000 index 000000000..d65d7634f --- /dev/null +++ b/.claude/commands/pull-request.md @@ -0,0 +1 @@ +../../.agents/skills/pull-request/SKILL.md \ No newline at end of file diff --git a/.claude/skills/pull-request/SKILL.md b/.claude/skills/pull-request/SKILL.md new file mode 120000 index 000000000..ea4144ba2 --- /dev/null +++ b/.claude/skills/pull-request/SKILL.md @@ -0,0 +1 @@ +../../../.agents/skills/pull-request/SKILL.md \ No newline at end of file diff --git a/.github/instructions/pull-request.instructions.md b/.github/instructions/pull-request.instructions.md new file mode 120000 index 000000000..d65d7634f --- /dev/null +++ b/.github/instructions/pull-request.instructions.md @@ -0,0 +1 @@ +../../.agents/skills/pull-request/SKILL.md \ No newline at end of file diff --git a/.github/prompts/pull-request.prompt.md b/.github/prompts/pull-request.prompt.md new file mode 120000 index 000000000..d65d7634f --- /dev/null +++ b/.github/prompts/pull-request.prompt.md @@ -0,0 +1 @@ +../../.agents/skills/pull-request/SKILL.md \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..002728a2a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,41 @@ +# Repository Guidelines + +## Project Structure & Module Organization + +StudyU is a Melos-managed Dart/Flutter workspace. The root `pubspec.yaml` defines the workspace packages: `app`, `designer_v2`, `core`, and `flutter_common`. + +- `app/`: participant-facing Flutter app, including `lib/`, `assets/`, platform folders, and widget tests. +- `designer_v2/`: study designer Flutter app, with feature modules under `lib/features/` and integration tests under `integration_test/`. +- `core/`: shared domain models and utilities; generated serialization files are committed. +- `flutter_common/`: shared Flutter utilities, env files, and common UI/support code. +- `supabase/` and `database/`: backend/local database setup and documentation. + +## Build, Test, and Development Commands + +Use FVM and Melos from the repository root. Run `fvm install` if the configured SDK is missing. + +- `dart pub get`: installs root dependencies. +- `melos bootstrap`: links workspace packages and installs package dependencies. +- `melos run app`: runs the StudyU app on Chrome at port `8080`. +- `melos run designer_v2`: runs Designer v2 on Chrome at port `8081`. +- `melos run dev:app` or `melos run dev:designer_v2`: runs against `.env.dev`. +- `melos run local:app` or `melos run local:designer_v2`: runs against `.env.local`. +- `melos run generate`: runs `build_runner` for generated Dart files. +- `melos run qualitycheck`: formats, regenerates, and analyzes the workspace. +- `melos run build:web`: builds both web apps. + +## Coding Style & Naming Conventions + +Follow Effective Dart and the shared `analysis_options.yaml`, which includes `package:lint/strict.yaml`. Use `melos format` before committing. Keep Dart files `snake_case.dart`, classes and widgets `UpperCamelCase`, and members `lowerCamelCase`. Generated `*.g.dart` files are excluded from analysis but must be regenerated and committed when model annotations change. + +## Testing Guidelines + +Tests use Flutter/Dart test tooling. Place unit and widget tests under each package's `test/` directory and Designer integration tests under `designer_v2/integration_test/`. Prefer names ending in `_test.dart`, matching the feature or model, for example `filter_evaluator_test.dart`. Run all package tests with `melos run test`; run a focused package test with `cd designer_v2 && flutter test`. + +## Commit & Pull Request Guidelines + +Use Conventional Commits, as seen in history: `fix: remove redundant fitbit label`, `feat(designer): move fitbit credentials...`, `chore: update deps + ios deps`. Keep commits scoped and include generated files when applicable. Pull requests should describe the change, link related issues, list verification commands, and include screenshots or recordings for UI changes. + +## Security & Configuration Tips + +Do not commit secrets. Environment templates live in `flutter_common/lib/envs/`; select them with `--dart-define=STUDYU_ENV=.env.dev` or `.env.local`. Use development or local Supabase instances for routine work; see `supabase/README.md` for local backend setup. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 000000000..47dc3e3d8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file