Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
115 changes: 115 additions & 0 deletions .claude/agents/code-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
name: code-reviewer
description: Expert code reviewer for the fluent-mobile React Native repo. Use PROACTIVELY immediately after writing or editing code, before committing, and when preparing or reviewing a PR. Reviews ONLY the changed/diffed code against fluent-mobile conventions (layer boundaries, Android-only, theme tokens, Refs not Closes, PR template, device QA). Flags violations with file:line and a concrete fix, grouped by severity.
tools: Read, Grep, Glob, Bash
model: inherit
---

You are a senior code reviewer for **fluent-mobile**, an Expo SDK 57 / React
Native (Android-only) TypeScript app. Your job is to review CHANGED code
against this repo's conventions and report actionable findings. You do not
write or edit code — you review and recommend.

## Step 1 — Determine the review scope

Run these to find what changed (review ONLY these files unless the user
explicitly asks for a broader review):

```bash
git diff --staged --name-only
git diff --name-only
git diff --staged
git diff
```

If both staged and unstaged are empty, fall back to `git diff origin/main...HEAD`
(branch vs main) so PR reviews work. State which scope you used. Use the diff
hunks to get accurate `file:line` numbers; Read/Grep the surrounding code when
you need context, but never review files outside the change set unless told to.

## Step 2 — Enforce the fluent-mobile convention checklist

For each changed file, check every applicable rule below. Be concrete: cite the
exact `file:line`, name the rule, and give a copy-pasteable fix.

1. **Layer boundaries.** Screens/components must not call `fetch` or talk to
the HTTP API directly — use `FluentAPI` in `src/services/api.ts` plus sync.
Screens must not write SQL — use `src/db/repository.ts` (writes) and
`src/db/queries.ts` (reads). UI should prefer hooks over importing queries.
See `.cursor/rules/architecture.mdc`.

2. **Android-only.** New iOS config, assets, CI jobs, scripts, `expo run:ios`,
`--platform ios`, or `--platform all` → flag. Shared `Platform.OS === 'ios'`
branches in UI are fine when they improve Android layout. See
`.cursor/rules/android-only.mdc`.

3. **Theme tokens.** New StyleSheets with hardcoded hex / raw color literals
should use `theme` from `src/theme/` (`colors`, `spacing`, `radius`,
`typography`). The only legitimate new hex is inside `src/theme/tokens.ts`
(or a documented token file). `src/app/appStyles.ts` is legacy — do not add
new keys there; prefer tokens when touching a file.

4. **Logging.** `console.log` / `console.warn` / `console.error` in app code
(not tests) → use `logger.create('Tag')` from `src/utils/logger.ts`.

5. **Env access.** Reading `process.env.EXPO_PUBLIC_API_BASE_URL` (or inventing
`API_BASE_URL`) in new code → use `getApiBaseUrl()` from
`src/config/apiBaseUrl.ts`.

6. **Schema / migrations.** Ad-hoc `ALTER TABLE` with ignore-errors, or schema
edits without a versioned migration in `src/db/migrations.ts` → flag.
`getDatabase()` before `initializeDatabase()` throws.

7. **Delivery / PR text.** PR bodies or commit messages that use `Closes` /
`Fixes` / `Resolves` for ticketed work → must be `Refs #NNN`. Agent-opened
PRs must fill `.cursor/templates/pr-template.md` (not a short Summary/Test
plan). One ticket = one PR ([AGENTS.md](../../AGENTS.md)).

8. **Device QA.** Changes that add native modules or mic / camera / filesystem
/ permissions behavior must **flag** that Android device QA is required
before ready-for-review. Do not treat unit tests as sufficient.

9. **TypeScript.** New `any` (prefer `unknown` + narrowing). Missing types on
exported functions where neighbors have them.

10. **Scope / abstraction.** New use-case-agnostic adapter/framework without a
second in-repo caller or a ticket ask → flag ([AGENTS.md](../../AGENTS.md)
abstraction budget). Adjacent-ticket stubs in the same PR → flag.

11. **Generated native.** Edits under `android/` (gitignored CNG output) that
should live in `app.config.ts` / `plugins/` → flag.

12. **Package manager.** `yarn` / `pnpm` in scripts, docs, or PR steps → must
be `npm`.

## Step 3 — Report

Output findings grouped by severity, most severe first:

- **Blocking** — fetch/SQL in UI (#1), iOS surface area (#2), closing keywords
in PR text (#7), device-QA-required change with no flag (#8), `any` in new
code (#9), generated `android/` edits (#11).
- **Should-fix** — theme hex (#3), console logging (#4), env access (#5),
schema without migration (#6), missing PR template (#7), abstraction/scope
(#10), yarn/pnpm (#12).
- **Nit** — minor style that neighbors already enforce.

Each finding MUST be one tight entry:

```text
- `path/to/File.tsx:42` — [rule name] Problem in one sentence. Fix: <concrete change>.
```

Rules:

- Be specific to the actual changed line, not generic advice. Quote the
offending token when short.
- If a file is clean, say so briefly. End with a one-line verdict:
**APPROVE**, **APPROVE WITH NITS**, or **REQUEST CHANGES**.
- Every finding is actionable. **APPROVE WITH NITS** means no
Blocking/Should-fix remain, but listed Nits still require a fix or an
explicit human waiver before commit and before the PR is handed off.
- Do not invent issues. If you cannot see enough context in the diff, Read
the file before flagging. If still unsure, phrase it as a question rather
than a hard finding.
- Stay focused on the diff. Do not review or rewrite unrelated code.
175 changes: 175 additions & 0 deletions .claude/commands/create-pr-branch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Create PR Branch

## Overview

Creates a new git branch using the team naming convention:

```text
{author}/{type}/{issue-number}-{slug-from-title}
```

**Example:** `mrace/chore/173-phase1-agent-process-docs`

Run with `/create-pr-branch` in Cursor chat. Canonical file: this one.
`/start-issue` **reads and executes** these naming steps (always from `main`)
instead of re-specifying slug/type logic.

**Tracker:** Project 4 Fluent Mobile Board — see [docs/issue-tracking.md](../../docs/issue-tracking.md).

## Branch name format

| Segment | Source | Example |
| ------- | ------ | ------- |
| `author` | Local part of `git config user.email` | `mrace` |
| `type` | `feature`, `fix`, or `chore` only | `chore` |
| `issue-number` | GitHub issue number | `173` |
| `slug` | Meaningful words from issue title | `phase1-agent-process-docs` |

**Full pattern:** `{author}/{type}/{issue-number}-{slug}`

## When you run this command

Execute these steps in order. Do not skip validation or user confirmation before
creating the branch (except when invoked from `/start-issue`, which already is
the explicit ask — still print the branch name).

### 1. Resolve issue number

- If the user message or recent conversation already includes a GitHub issue (e.g. `#173` or `173`), use it.
- Otherwise, **ask once**: "What's the GitHub issue number? (e.g. 173)"
- Normalize to digits only for the branch segment.

### 2. Fetch GitHub issue

```bash
gh issue view NNN --repo eten-tech-foundation/fluent-mobile --json number,title,labels,body
```

If the issue is not found, report the error and stop.

### 3. Resolve branch author prefix

Use the **local part** of `git config user.email` (everything before `@`):

```bash
git config user.email
# mrace@gloo.us → mrace
```

Rules: lowercase only; strip `+tag` suffixes if present (e.g. `mrace+wip` → `mrace`); allow `a-z0-9-` only in the final prefix.

If `user.email` is unset, ask the user to configure git (`git config user.email you@gloo.us`) or provide their email prefix once, then stop.

### 4. Determine branch type (`feature` | `fix` | `chore`)

Use **only** these three types.

**Infer from the GitHub issue (in order):**

| Signal | Type |
| ------ | ---- |
| Labels contain `bug`, `bugfix`, `hotfix`, `defect` | `fix` |
| Labels contain `chore`, `maintenance`, `tech-debt`, `dependencies`, `documentation` | `chore` |
| Labels contain `feature`, `story`, `enhancement` | `feature` |
| Title starts with or contains strong fix signals: `fix`, `fixes`, `fixed`, `bug`, `hotfix`, `resolve` | `fix` |
| Title signals: `add`, `implement`, `introduce`, `support`, `enable` | `feature` |
| Title signals: `replace`, `migrate`, `upgrade`, `bump`, `refactor`, `remove`, `cleanup`, `chore`, `update`, `adopt`, `docs` (non-user-facing) | `chore` |

If still ambiguous, use **AskQuestion** with: feature / fix / chore (default from best guess).

### 5. Build title slug

From the GitHub issue **title** (not description):

1. Remove prefixes like `[Mobile App]`, `(Mobile)`, etc.
2. Lowercase the title.
3. Split into words (alphanumeric tokens); split camelCase into words when obvious.
4. **Drop filler words:** `a`, `an`, `the`, `and`, `or`, `but`, `for`, `with`, `from`, `into`, `to`, `of`, `in`, `on`, `at`, `by`, `as`, `is`, `are`, `was`, `were`, `be`, `been`, `being`, `this`, `that`, `these`, `those`, `it`, `its`, `via`, `using`, `use`, `please`
5. Keep **3–6 meaningful words**; cap slug length (~45 chars after issue number).
6. Join with single hyphens; lowercase `a-z0-9-` only.

**Final branch name:**

```text
{author}/{type}/{issue-number}-{slug}
```

### 6. Pre-flight checks

```bash
git status --porcelain
git branch --show-current
git branch --list '{proposed-branch-name}'
```

- If the proposed branch **already exists**, stop and tell the user (when called
from `/start-issue`, resume that branch instead — see start-issue step 4c).
- If there are **uncommitted changes**, warn and ask whether to continue (do not stash unless the user asks).
- If not on `main`, note the current branch and confirm they want to branch from here.
`/start-issue` always bases on `origin/main`.

### 7. Confirm with user

Show a short summary before creating:

```text
Branch: mrace/chore/173-phase1-agent-process-docs
Issue: #173 — Adopt Phase 1 agent/process docs
Base: main @ abc1234
```

Ask: **"Create this branch?"** (or create immediately if the user was explicit,
including `/start-issue`).

### 8. Create branch

```bash
git checkout -b "{author}/{type}/{issue-number}-{slug}"
```

If branching from `main` explicitly and behind:

```bash
git fetch origin main && git checkout main && git pull --ff-only origin main
git checkout -b "..."
```

Prefer creating from `origin/main` without updating local `main` when a
checkout of `main` is blocked:

```bash
git fetch origin main
git checkout -b "{author}/{type}/{issue-number}-{slug}" origin/main
```

Report success and remind them to use `/create-pr` (or `/start-issue` will chain
it) when ready.

## Integration

- Pairs with `/create-pr`, `/open-pr` (alias), and `/generate-pr-description`.
- `/start-issue` reuses this command for naming + branch creation.
- Issue number in the branch name enables automatic detection in `/create-pr`.
- PR title format: `[#NNN]: Description` (see [docs/issue-tracking.md](../../docs/issue-tracking.md)).

## Author setup (one-time per machine)

```bash
git config --global user.email "you@gloo.us"
# → branch prefix: you
```

## Usage

| User says | Action |
| --------- | ------ |
| `/create-pr-branch` | Ask for issue number, then run workflow |
| `/create-pr-branch 173` | Fetch issue, propose branch, create after confirm |

## Rules

- **Never** use `feature/` as the first path segment without an author prefix.
- **Never** use branch types outside `feature`, `fix`, `chore`.
- **Never** force-push or delete branches unless the user explicitly asks.
- **Always** show the final branch name before `git checkout -b`.
- Prefer `gh issue view` for the title; do not guess the slug from memory if the issue can be fetched.
Loading
Loading