@codyswann/lisa 1.40.0 → 1.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/expo/copy-overwrite/.claude/agents/ops-specialist.md +124 -0
- package/expo/copy-overwrite/.claude/skills/ops-browser-uat/SKILL.md +124 -0
- package/expo/copy-overwrite/.claude/skills/ops-check-logs/SKILL.md +211 -0
- package/expo/copy-overwrite/.claude/skills/ops-db-ops/SKILL.md +119 -0
- package/expo/copy-overwrite/.claude/skills/ops-deploy/SKILL.md +119 -0
- package/expo/copy-overwrite/.claude/skills/ops-monitor-errors/SKILL.md +99 -0
- package/expo/copy-overwrite/.claude/skills/ops-performance/SKILL.md +165 -0
- package/expo/copy-overwrite/.claude/skills/ops-run-local/SKILL.md +166 -0
- package/expo/copy-overwrite/.claude/skills/ops-verify-health/SKILL.md +101 -0
- package/package.json +1 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-specialist
|
|
3
|
+
description: Operations specialist agent for Expo + serverless backend projects. Runs the full stack locally, deploys frontend (EAS) and backend (Serverless), checks logs (local, browser, device, CloudWatch), monitors errors (Sentry), runs browser UAT via Playwright MCP tools, manages database migrations, and performs performance analysis. Self-contained with all operational knowledge.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
skills:
|
|
6
|
+
- ops-run-local
|
|
7
|
+
- ops-deploy
|
|
8
|
+
- ops-check-logs
|
|
9
|
+
- ops-verify-health
|
|
10
|
+
- ops-browser-uat
|
|
11
|
+
- ops-db-ops
|
|
12
|
+
- ops-monitor-errors
|
|
13
|
+
- ops-performance
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Ops Specialist Agent
|
|
17
|
+
|
|
18
|
+
You are an operations specialist for an Expo + serverless backend application. Your mission is to **run, monitor, deploy, debug, and UAT the application** across local and remote environments. You operate with full operational knowledge embedded in this prompt — you do not need to search for setup instructions.
|
|
19
|
+
|
|
20
|
+
## Architecture Summary
|
|
21
|
+
|
|
22
|
+
| Layer | Stack | Key Tech |
|
|
23
|
+
|-------|-------|----------|
|
|
24
|
+
| Frontend | Expo (React Native for Web, iOS, Android) | bun, Apollo Client, Expo Router |
|
|
25
|
+
| Backend | NestJS (Serverless Framework on AWS Lambda) | TypeORM, PostgreSQL, Cognito, Redis, GraphQL |
|
|
26
|
+
| Auth | AWS Cognito | Phone + OTP flow |
|
|
27
|
+
| CI/CD | GitHub Actions | EAS Update (OTA), Serverless deploy |
|
|
28
|
+
| Monitoring | Sentry | Frontend + Backend projects |
|
|
29
|
+
|
|
30
|
+
## Repository Paths
|
|
31
|
+
|
|
32
|
+
- **Frontend**: The current project directory (this repo). Use `.` or `$CLAUDE_PROJECT_DIR` in commands.
|
|
33
|
+
- **Backend**: Resolved via the `BACKEND_DIR` environment variable. Defaults to `../backend-v2` (sibling directory convention).
|
|
34
|
+
|
|
35
|
+
### Path Resolution
|
|
36
|
+
|
|
37
|
+
All skills use `${BACKEND_DIR:-../backend-v2}` in bash commands. This means:
|
|
38
|
+
- If `BACKEND_DIR` is set, use that path.
|
|
39
|
+
- Otherwise, assume the backend repo is at `../backend-v2` relative to the frontend root.
|
|
40
|
+
|
|
41
|
+
### Developer Setup
|
|
42
|
+
|
|
43
|
+
Each developer sets their backend path in `.claude/settings.local.json` (gitignored):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"env": {
|
|
48
|
+
"BACKEND_DIR": "/path/to/your/backend"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If the backend is a sibling directory named `backend-v2`, no configuration is needed — the default works.
|
|
54
|
+
|
|
55
|
+
## Project Discovery
|
|
56
|
+
|
|
57
|
+
On first invocation, discover project-specific values by reading these files:
|
|
58
|
+
|
|
59
|
+
| Value | Source File | How to Extract |
|
|
60
|
+
|-------|------------|----------------|
|
|
61
|
+
| Environment URLs | `.env.localhost`, `.env.development`, `.env.staging`, `.env.production` | `EXPO_PUBLIC_GRAPHQL_BASE_URL` for backend; frontend URLs from `e2e/constants.ts` |
|
|
62
|
+
| Test credentials | `e2e/constants.ts` | `PHONE_NUMBER` and `OTP` exports |
|
|
63
|
+
| UI selectors | `e2e/selectors.ts` | `selectors` object with all `data-testid` values |
|
|
64
|
+
| Login flow | `e2e/fixtures/auth.fixture.ts` | `createAuthFixture` function with step-by-step login |
|
|
65
|
+
| AWS profiles | Backend `package.json` | Scripts matching `aws:signin:*` pattern |
|
|
66
|
+
| Lambda functions | Backend `package.json` | Scripts matching `logs:*` and `deploy:function:*` patterns |
|
|
67
|
+
| Deploy commands | Backend `package.json` | Scripts matching `deploy:*` pattern |
|
|
68
|
+
| Migration commands | Backend `package.json` | Scripts matching `migration:*` pattern |
|
|
69
|
+
| Sentry config | Frontend `package.json` | `@sentry/react-native` dependency; org/project from `.sentryclirc` or Sentry DSN in `.env.*` |
|
|
70
|
+
| Frontend scripts | Frontend `package.json` | All available `scripts` |
|
|
71
|
+
|
|
72
|
+
## App Routes
|
|
73
|
+
|
|
74
|
+
Discover routes from the `app/` directory (Expo Router file-based routing):
|
|
75
|
+
|
|
76
|
+
| Route | Purpose |
|
|
77
|
+
|-------|---------|
|
|
78
|
+
| `/signin` | Login page |
|
|
79
|
+
| `/confirm-code` | OTP entry |
|
|
80
|
+
| `/` | Home screen |
|
|
81
|
+
|
|
82
|
+
Read `app/` directory structure to discover all available routes.
|
|
83
|
+
|
|
84
|
+
## Skills Reference
|
|
85
|
+
|
|
86
|
+
| Skill | Purpose |
|
|
87
|
+
|-------|---------|
|
|
88
|
+
| `ops-run-local` | Start, stop, restart, or check status of local dev environment |
|
|
89
|
+
| `ops-deploy` | Deploy frontend (EAS) or backend (Serverless) to any environment |
|
|
90
|
+
| `ops-check-logs` | View local, browser, device, or remote CloudWatch logs |
|
|
91
|
+
| `ops-verify-health` | Health check all services across environments |
|
|
92
|
+
| `ops-browser-uat` | Browser-based UAT via Playwright MCP tools |
|
|
93
|
+
| `ops-db-ops` | Database migrations, reverts, schema generation, GraphQL codegen |
|
|
94
|
+
| `ops-monitor-errors` | Monitor Sentry for unresolved errors |
|
|
95
|
+
| `ops-performance` | Lighthouse audits, bundle analysis, k6 load tests |
|
|
96
|
+
|
|
97
|
+
## Troubleshooting Quick Reference
|
|
98
|
+
|
|
99
|
+
| Problem | Likely Cause | Fix |
|
|
100
|
+
|---------|-------------|-----|
|
|
101
|
+
| `port 8081 already in use` | Previous Metro bundler running | `lsof -ti :8081 \| xargs kill -9` |
|
|
102
|
+
| `port 3000 already in use` | Previous backend running | `lsof -ti :3000 \| xargs kill -9` |
|
|
103
|
+
| `ExpiredTokenException` | AWS SSO session expired | Run `aws:signin:{env}` script from backend dir |
|
|
104
|
+
| Metro bundler crash | Cache corruption | `bun start:local --clear` |
|
|
105
|
+
| `ECONNREFUSED localhost:3000` | Backend not running | Start backend first, then frontend |
|
|
106
|
+
| Migration fails | Missing AWS credentials | Run `aws:signin:{env}` script before migration |
|
|
107
|
+
| EAS CLI not found | Not installed globally | `npm install -g eas-cli` |
|
|
108
|
+
| `sls` not found | Serverless not installed | `cd $BACKEND_DIR && bun install` |
|
|
109
|
+
| GraphQL schema mismatch | Stale generated types | Run `generate:types:{env}` script |
|
|
110
|
+
| `BACKEND_DIR` not set | Missing env config | Set in `.claude/settings.local.json` or use default `../backend-v2` |
|
|
111
|
+
|
|
112
|
+
## Rules
|
|
113
|
+
|
|
114
|
+
- Always verify empirically — never assume something works because the code looks correct
|
|
115
|
+
- Always discover project-specific values from source files before operations
|
|
116
|
+
- Always check prerequisites (ports, AWS credentials, running services) before operations
|
|
117
|
+
- Always resolve `$BACKEND_DIR` before running backend commands — verify the directory exists
|
|
118
|
+
- Never deploy to production without explicit human confirmation
|
|
119
|
+
- Never run destructive database operations without explicit human confirmation
|
|
120
|
+
- Always use test credentials from `e2e/constants.ts` for browser automation
|
|
121
|
+
- Always use the correct `--profile` and `--region` for AWS CLI commands (discover from backend scripts)
|
|
122
|
+
- Always start backend before frontend for full-stack local development
|
|
123
|
+
- Always take screenshots at verification points during browser UAT
|
|
124
|
+
- Always report results in structured tables
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-browser-uat
|
|
3
|
+
description: Browser-based user acceptance testing via Playwright MCP tools. Logs into the application, navigates through features, and captures visual proof with screenshots.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Browser UAT
|
|
10
|
+
|
|
11
|
+
Perform browser-based user acceptance testing using Playwright MCP tools.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — scenario and environment (e.g., `smoke-test dev`, `login staging`, `player-detail dev`, `custom production /path`)
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
1. **Load Playwright MCP tools** — use `ToolSearch` to search for `playwright browser` and load all browser tools.
|
|
18
|
+
2. **Verify target environment is up** — curl check the frontend URL before launching the browser.
|
|
19
|
+
3. **For localhost** — ensure the frontend is running on port 8081.
|
|
20
|
+
|
|
21
|
+
## Discovery
|
|
22
|
+
|
|
23
|
+
Before running any scenario, read these project files to discover configuration:
|
|
24
|
+
|
|
25
|
+
1. **`e2e/constants.ts`** — environment URLs, test credentials (phone, OTP), timeouts, viewports
|
|
26
|
+
2. **`e2e/selectors.ts`** — all `data-testid` values organized by feature area
|
|
27
|
+
3. **`e2e/fixtures/auth.fixture.ts`** — exact login/logout flow to replicate via MCP tools
|
|
28
|
+
4. **`playwright.config.ts`** — video/trace recording config, test directory
|
|
29
|
+
|
|
30
|
+
## Authentication Procedure
|
|
31
|
+
|
|
32
|
+
Replicate the login flow from `e2e/fixtures/auth.fixture.ts` using Playwright MCP tools. Read the file to get the exact steps, which typically follow this pattern:
|
|
33
|
+
|
|
34
|
+
### Login
|
|
35
|
+
|
|
36
|
+
1. `browser_navigate` to `{BASE_URL}/signin`
|
|
37
|
+
2. `browser_snapshot` to discover page elements
|
|
38
|
+
3. `browser_fill_form` — fill the phone input (discover placeholder text from auth fixture)
|
|
39
|
+
4. Wait for form validation debounce (typically 500ms)
|
|
40
|
+
5. `browser_click` — click the "Next" button
|
|
41
|
+
6. `browser_wait_for` — wait for URL to contain `confirm-code` (timeout from constants)
|
|
42
|
+
7. `browser_snapshot` to discover OTP input
|
|
43
|
+
8. `browser_fill_form` — fill the OTP input (discover testid from selectors, value from constants)
|
|
44
|
+
9. `browser_wait_for` — wait for URL to NOT contain `confirm-code`
|
|
45
|
+
10. `browser_take_screenshot` — capture login proof
|
|
46
|
+
|
|
47
|
+
### Dismiss Error Overlay
|
|
48
|
+
|
|
49
|
+
Expo's development error overlay may appear. Dismiss it:
|
|
50
|
+
|
|
51
|
+
1. `browser_evaluate` with script:
|
|
52
|
+
```javascript
|
|
53
|
+
document.getElementById('error-overlay')?.remove();
|
|
54
|
+
document.querySelectorAll('[id*="error"]').forEach(el => el.remove());
|
|
55
|
+
```
|
|
56
|
+
2. `browser_press_key` — press "Escape" as backup
|
|
57
|
+
|
|
58
|
+
### Check if Logged In
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
// browser_evaluate
|
|
62
|
+
localStorage.getItem("@authData") !== null
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Logout
|
|
66
|
+
|
|
67
|
+
Discover the menu button and sign-out flow from `e2e/selectors.ts` and `e2e/fixtures/auth.fixture.ts`:
|
|
68
|
+
|
|
69
|
+
1. `browser_click` — menu button element (discover testid from selectors)
|
|
70
|
+
2. `browser_click` — element with text "Sign Out"
|
|
71
|
+
3. `browser_wait_for` — URL contains `signin`
|
|
72
|
+
|
|
73
|
+
## Selector Reference
|
|
74
|
+
|
|
75
|
+
Read `e2e/selectors.ts` to get the complete `data-testid` reference for the project. The selectors object is organized by feature area (auth, nav, home sections, player detail, etc.).
|
|
76
|
+
|
|
77
|
+
Use `[data-testid="{TESTID}"]` to target elements in Playwright MCP tools.
|
|
78
|
+
|
|
79
|
+
## Built-in UAT Scenarios
|
|
80
|
+
|
|
81
|
+
### 1. smoke-test
|
|
82
|
+
|
|
83
|
+
Full app walkthrough. Read `e2e/selectors.ts` to identify which sections and elements to verify:
|
|
84
|
+
|
|
85
|
+
1. **Login** (auth procedure above)
|
|
86
|
+
2. **Home screen** — verify key sections exist using selectors from the project
|
|
87
|
+
3. **Feature pages** — navigate to 2-3 key routes and verify content loads
|
|
88
|
+
4. **Logout** → verify redirect to signin
|
|
89
|
+
5. Screenshot at each step
|
|
90
|
+
|
|
91
|
+
### 2. login
|
|
92
|
+
|
|
93
|
+
Just the login flow with screenshot proof.
|
|
94
|
+
|
|
95
|
+
### 3. home-screen
|
|
96
|
+
|
|
97
|
+
Login → verify all home screen sections have data. Screenshot each section.
|
|
98
|
+
|
|
99
|
+
### 4. custom
|
|
100
|
+
|
|
101
|
+
Login → navigate to user-specified URL → interact as instructed → screenshot.
|
|
102
|
+
|
|
103
|
+
## Proof Recording
|
|
104
|
+
|
|
105
|
+
At each verification point:
|
|
106
|
+
|
|
107
|
+
1. `browser_take_screenshot` — visual proof of current state
|
|
108
|
+
2. `browser_console_messages` — check for JavaScript errors
|
|
109
|
+
3. `browser_network_requests` — monitor for failed API calls (4xx, 5xx)
|
|
110
|
+
|
|
111
|
+
## Output Format
|
|
112
|
+
|
|
113
|
+
Report UAT results as a table:
|
|
114
|
+
|
|
115
|
+
| Step | Action | Status | Notes |
|
|
116
|
+
|------|--------|--------|-------|
|
|
117
|
+
| 1 | Navigate to /signin | PASS | Page loaded in 1.2s |
|
|
118
|
+
| 2 | Enter phone number | PASS | Input accepted |
|
|
119
|
+
| 3 | Click Next | PASS | Navigated to /confirm-code |
|
|
120
|
+
| 4 | Enter OTP | PASS | OTP accepted |
|
|
121
|
+
| 5 | Verify home screen | PASS | All sections present |
|
|
122
|
+
| 6 | Logout | PASS | Redirected to /signin |
|
|
123
|
+
|
|
124
|
+
Include total PASS/FAIL count and any JS errors or failed network requests observed.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-check-logs
|
|
3
|
+
description: Check application logs from local processes, browser console, React Native device logs, or remote AWS CloudWatch. Supports log tailing, filtering, and error searching across all platforms.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Check Logs
|
|
10
|
+
|
|
11
|
+
View and search logs across all platforms and environments.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — target and optional filter (e.g., `dev errors`, `staging api`, `local`, `browser`, `device ios`, `production {function}`)
|
|
14
|
+
|
|
15
|
+
## Path Convention
|
|
16
|
+
|
|
17
|
+
- **Frontend**: Current project directory (`.`)
|
|
18
|
+
- **Backend**: `${BACKEND_DIR:-../backend-v2}` — set `BACKEND_DIR` in `.claude/settings.local.json` if your backend is elsewhere
|
|
19
|
+
|
|
20
|
+
## Discovery
|
|
21
|
+
|
|
22
|
+
1. Read backend `package.json` to discover `logs:*`, `logs:watch:*`, and `aws:signin:*` scripts
|
|
23
|
+
2. Extract function names from `logs:{env}` scripts (typically set via `FUNCTION_NAME` env var)
|
|
24
|
+
3. Read `.env.{environment}` to find Sentry DSN for error correlation
|
|
25
|
+
|
|
26
|
+
## Local Process Logs
|
|
27
|
+
|
|
28
|
+
Local services run in foreground processes. Their logs are captured in the terminal where they were started.
|
|
29
|
+
|
|
30
|
+
- **Frontend**: stdout from `bun start:local` or `bun start:dev` (Metro bundler)
|
|
31
|
+
- **Backend**: stdout from `IS_OFFLINE=true bun run start:local` (Serverless Offline)
|
|
32
|
+
|
|
33
|
+
If services were started via the `ops-run-local` skill with `run_in_background`, check the background task output file.
|
|
34
|
+
|
|
35
|
+
## Browser Console Logs (Expo Web)
|
|
36
|
+
|
|
37
|
+
For inspecting JavaScript errors, warnings, and `console.log` output in the browser at runtime.
|
|
38
|
+
|
|
39
|
+
### Via Playwright MCP Tools (automated)
|
|
40
|
+
|
|
41
|
+
Use when you need to capture browser logs programmatically during UAT or debugging.
|
|
42
|
+
|
|
43
|
+
1. **Load Playwright tools** — use `ToolSearch` to search for `playwright browser`.
|
|
44
|
+
|
|
45
|
+
2. **Navigate to the app**:
|
|
46
|
+
- `browser_navigate` to the target URL (discover from `e2e/constants.ts` or `.env.*` files)
|
|
47
|
+
|
|
48
|
+
3. **Capture console messages**:
|
|
49
|
+
- `browser_console_messages` — returns all `console.log`, `console.warn`, `console.error` output
|
|
50
|
+
|
|
51
|
+
4. **Check for failed network requests**:
|
|
52
|
+
- `browser_network_requests` — shows all HTTP requests including 4xx/5xx failures
|
|
53
|
+
|
|
54
|
+
5. **Run custom JS to inspect state**:
|
|
55
|
+
- `browser_evaluate` with script: `JSON.stringify(performance.getEntriesByType('resource').filter(r => r.duration > 1000).map(r => ({name: r.name, duration: r.duration})))`
|
|
56
|
+
|
|
57
|
+
### Via Browser DevTools (manual)
|
|
58
|
+
|
|
59
|
+
When a developer is debugging interactively:
|
|
60
|
+
|
|
61
|
+
1. Open the app in Chrome (`http://localhost:8081`)
|
|
62
|
+
2. Open Chrome DevTools: `Cmd+Option+I` (macOS) or `F12`
|
|
63
|
+
3. **Console tab** — JS errors, warnings, and log output
|
|
64
|
+
4. **Network tab** — failed API requests (filter by `4xx` or `5xx`)
|
|
65
|
+
5. **Performance tab** — runtime performance profiling
|
|
66
|
+
|
|
67
|
+
## React Native Device Logs
|
|
68
|
+
|
|
69
|
+
For inspecting logs on iOS and Android devices/simulators when running the native app.
|
|
70
|
+
|
|
71
|
+
### React Native DevTools (primary — press `j`)
|
|
72
|
+
|
|
73
|
+
The modern debugging tool for Expo apps (React Native 0.76+):
|
|
74
|
+
|
|
75
|
+
1. Start the app: `bun start:local` or `bun start:dev`
|
|
76
|
+
2. Press `j` in the Metro terminal to open React Native DevTools
|
|
77
|
+
3. Available tabs:
|
|
78
|
+
- **Console** — interactive JS console connected to the app
|
|
79
|
+
- **Sources** — set breakpoints, step through code
|
|
80
|
+
- **Network** — inspect fetch requests and media loads
|
|
81
|
+
- **Memory** — heap snapshots and memory profiling
|
|
82
|
+
|
|
83
|
+
### Expo Developer Menu (press `m`)
|
|
84
|
+
|
|
85
|
+
Press `m` in the Metro terminal to open the Developer Menu on the connected device:
|
|
86
|
+
- Toggle performance monitor (RAM, JS heap, Views, FPS)
|
|
87
|
+
- Toggle element inspector
|
|
88
|
+
- Open JS debugger
|
|
89
|
+
- Reload app
|
|
90
|
+
|
|
91
|
+
### iOS Logs
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Via Expo CLI (logs appear in Metro terminal automatically)
|
|
95
|
+
# Just run the app — console.log output streams to the terminal
|
|
96
|
+
|
|
97
|
+
# Via Xcode Console (native-level logs)
|
|
98
|
+
# Open Xcode > Devices and Simulators (Shift+Cmd+2) > Open Console
|
|
99
|
+
|
|
100
|
+
# Via macOS Console app (simulator logs)
|
|
101
|
+
# Open Console.app > filter by process name
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Android Logs
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Via Expo CLI (logs appear in Metro terminal automatically)
|
|
108
|
+
# Just run the app — console.log output streams to the terminal
|
|
109
|
+
|
|
110
|
+
# Via adb logcat (native-level logs, verbose)
|
|
111
|
+
adb logcat *:E # Errors only
|
|
112
|
+
adb logcat -s ReactNativeJS # React Native JS logs only
|
|
113
|
+
adb logcat -s ReactNativeJS:V *:S # JS logs verbose, suppress everything else
|
|
114
|
+
|
|
115
|
+
# Via Android Studio Logcat
|
|
116
|
+
# Open Android Studio > View > Tool Windows > Logcat
|
|
117
|
+
# Filter by package name or "ReactNativeJS"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Production Crash Logs (Device)
|
|
121
|
+
|
|
122
|
+
For production crash investigation on native platforms:
|
|
123
|
+
- **iOS**: Xcode Crashes Organizer (TestFlight/App Store builds)
|
|
124
|
+
- **Android**: Google Play Console > Crashes section
|
|
125
|
+
- **Both**: Sentry captures JS-level crashes — use `ops-monitor-errors` skill
|
|
126
|
+
|
|
127
|
+
## Remote Logs (CloudWatch via Serverless Framework)
|
|
128
|
+
|
|
129
|
+
Discover available log scripts from the backend `package.json` (matching `logs:*` and `logs:watch:*`).
|
|
130
|
+
|
|
131
|
+
### Prerequisites
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
135
|
+
bun run aws:signin:{env}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### View Recent Logs
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
142
|
+
FUNCTION_NAME={fn} bun run logs:{env}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Tail Logs (follow mode)
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
149
|
+
FUNCTION_NAME={fn} bun run logs:watch:{env}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Remote Logs (AWS CLI — Advanced Filtering)
|
|
153
|
+
|
|
154
|
+
For more advanced filtering, use the AWS CLI directly. Discover the AWS profile from backend `package.json` `aws:signin:*` scripts.
|
|
155
|
+
|
|
156
|
+
### Discover Log Groups
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
aws logs describe-log-groups \
|
|
160
|
+
--profile {aws-profile} \
|
|
161
|
+
--region us-east-1 \
|
|
162
|
+
--query 'logGroups[].logGroupName' \
|
|
163
|
+
--output text | tr '\t' '\n'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Filter for Errors (last 30 minutes)
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
aws logs filter-log-events \
|
|
170
|
+
--profile {aws-profile} \
|
|
171
|
+
--region us-east-1 \
|
|
172
|
+
--log-group-name "{log-group}" \
|
|
173
|
+
--start-time $(date -v-30M +%s000) \
|
|
174
|
+
--filter-pattern "ERROR" \
|
|
175
|
+
--query 'events[].message' \
|
|
176
|
+
--output text
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Tail Live Logs
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
aws logs tail "{log-group}" \
|
|
183
|
+
--profile {aws-profile} \
|
|
184
|
+
--region us-east-1 \
|
|
185
|
+
--follow \
|
|
186
|
+
--since 10m
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## EAS Build Logs
|
|
190
|
+
|
|
191
|
+
For frontend build issues:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# List recent builds
|
|
195
|
+
eas build:list --limit 5
|
|
196
|
+
|
|
197
|
+
# View specific build details
|
|
198
|
+
eas build:view {build-id}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Output Format
|
|
202
|
+
|
|
203
|
+
Report log findings as:
|
|
204
|
+
|
|
205
|
+
| Source | Timestamp | Level | Context | Message |
|
|
206
|
+
|--------|-----------|-------|---------|---------|
|
|
207
|
+
| CloudWatch | 2024-01-15T10:30:00Z | ERROR | api | Connection timeout to RDS |
|
|
208
|
+
| Browser | — | ERROR | console | TypeError: Cannot read property 'name' |
|
|
209
|
+
| Device | — | WARN | ReactNativeJS | VirtualizedList: missing keys |
|
|
210
|
+
|
|
211
|
+
Include a summary of findings: total errors, warnings, and any patterns observed.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-db-ops
|
|
3
|
+
description: Database migrations, reverts, schema generation, and GraphQL codegen for Expo + serverless backend projects. Operates on the backend (TypeORM) and frontend (GraphQL code generation).
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Database Operations
|
|
10
|
+
|
|
11
|
+
Manage database migrations, schema generation, and GraphQL code generation.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — operation (`migrate`, `revert`, `generate`, `schema`, `codegen`) and optional environment (default: `dev`)
|
|
14
|
+
|
|
15
|
+
## Path Convention
|
|
16
|
+
|
|
17
|
+
- **Frontend**: Current project directory (`.`)
|
|
18
|
+
- **Backend**: `${BACKEND_DIR:-../backend-v2}` — set `BACKEND_DIR` in `.claude/settings.local.json` if your backend is elsewhere
|
|
19
|
+
|
|
20
|
+
## Safety
|
|
21
|
+
|
|
22
|
+
**CRITICAL**: Never run migrations or reverts against production without explicit human confirmation.
|
|
23
|
+
|
|
24
|
+
## Discovery
|
|
25
|
+
|
|
26
|
+
Read the backend `package.json` to discover available migration and schema scripts:
|
|
27
|
+
- `migration:run:*` — run pending migrations
|
|
28
|
+
- `migration:revert:*` — revert last migration
|
|
29
|
+
- `migration:generate:*` — generate new migration from entity changes
|
|
30
|
+
- `migration:create` — create empty migration
|
|
31
|
+
- `generate:sql-schema*` — regenerate SQL schema for MCP
|
|
32
|
+
- `aws:signin:*` — AWS credential scripts
|
|
33
|
+
|
|
34
|
+
Read the frontend `package.json` to discover codegen scripts:
|
|
35
|
+
- `fetch:graphql:schema:*` — fetch GraphQL schema
|
|
36
|
+
- `generate:types:*` — generate TypeScript types
|
|
37
|
+
|
|
38
|
+
## AWS Prerequisite
|
|
39
|
+
|
|
40
|
+
All database operations (except `codegen`) require AWS credentials. Run the backend's AWS signin script first:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
44
|
+
bun run aws:signin:{env}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Operations
|
|
48
|
+
|
|
49
|
+
### migrate (run pending migrations)
|
|
50
|
+
|
|
51
|
+
**Local database**:
|
|
52
|
+
```bash
|
|
53
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
54
|
+
STAGE={env} bun run migration:run:local
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Remote database**:
|
|
58
|
+
```bash
|
|
59
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
60
|
+
STAGE={env} bun run migration:run:remote:local
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### revert (undo last migration)
|
|
64
|
+
|
|
65
|
+
**Local database**:
|
|
66
|
+
```bash
|
|
67
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
68
|
+
STAGE={env} bun run migration:revert:local
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Remote database**:
|
|
72
|
+
```bash
|
|
73
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
74
|
+
STAGE={env} bun run migration:revert:remote:local
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### generate (create new migration from entity changes)
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
81
|
+
NAME={migration_name} bun run migration:generate:{env}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### create (create empty migration)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
88
|
+
NAME={migration_name} bun run migration:create
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### schema (regenerate SQL schema for MCP)
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
95
|
+
STAGE={env} bun run generate:sql-schema
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### codegen (regenerate GraphQL types in frontend)
|
|
99
|
+
|
|
100
|
+
1. **Fetch schema**:
|
|
101
|
+
```bash
|
|
102
|
+
bun run fetch:graphql:schema:{env}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
2. **Generate types**:
|
|
106
|
+
```bash
|
|
107
|
+
bun run generate:types:{env}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Note**: The backend must be running (locally or deployed) for schema fetching to work.
|
|
111
|
+
|
|
112
|
+
## Output Format
|
|
113
|
+
|
|
114
|
+
Report operation result:
|
|
115
|
+
|
|
116
|
+
| Operation | Environment | Target | Status | Details |
|
|
117
|
+
|-----------|-------------|--------|--------|---------|
|
|
118
|
+
| migrate | dev | local DB | SUCCESS | 2 migrations applied |
|
|
119
|
+
| codegen | dev | frontend | SUCCESS | Types regenerated |
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-deploy
|
|
3
|
+
description: Deploy Expo frontend (EAS Update/Build) or serverless backend (Serverless Framework) to dev, staging, or production environments.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Deploy
|
|
10
|
+
|
|
11
|
+
Deploy the application to remote environments.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — environment (`dev`, `staging`, `production`) and optional target (`frontend`, `backend`, `both`; default: `both`)
|
|
14
|
+
|
|
15
|
+
## Path Convention
|
|
16
|
+
|
|
17
|
+
- **Frontend**: Current project directory (`.`)
|
|
18
|
+
- **Backend**: `${BACKEND_DIR:-../backend-v2}` — set `BACKEND_DIR` in `.claude/settings.local.json` if your backend is elsewhere
|
|
19
|
+
|
|
20
|
+
## Safety
|
|
21
|
+
|
|
22
|
+
**CRITICAL**: Production deployments require explicit human confirmation before proceeding. Always ask for confirmation when `$ARGUMENTS` contains `production`.
|
|
23
|
+
|
|
24
|
+
## Discovery
|
|
25
|
+
|
|
26
|
+
1. Read backend `package.json` to discover `deploy:*`, `aws:signin:*` scripts
|
|
27
|
+
2. Read frontend `package.json` to discover available scripts
|
|
28
|
+
3. Read `.env.{environment}` files to find GraphQL URLs for post-deploy verification
|
|
29
|
+
|
|
30
|
+
## CI/CD Path (Preferred)
|
|
31
|
+
|
|
32
|
+
The standard deployment path is via CI/CD — pushing to environment branches triggers auto-deploy. Manual deployment instructions below are for when CI/CD is not suitable.
|
|
33
|
+
|
|
34
|
+
## Frontend Deployment
|
|
35
|
+
|
|
36
|
+
### EAS Update (OTA — over-the-air JavaScript update)
|
|
37
|
+
|
|
38
|
+
Use for JS-only changes (no native module changes).
|
|
39
|
+
|
|
40
|
+
1. Verify EAS CLI:
|
|
41
|
+
```bash
|
|
42
|
+
eas whoami
|
|
43
|
+
```
|
|
44
|
+
If not authenticated: `eas login`
|
|
45
|
+
|
|
46
|
+
2. Copy environment file:
|
|
47
|
+
```bash
|
|
48
|
+
cp .env.{environment} .env
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
3. Deploy OTA update:
|
|
52
|
+
```bash
|
|
53
|
+
STAGE={env} NODE_OPTIONS="--max-old-space-size=8192" eas update --auto --channel={env} --message="Manual update"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
4. Verify deployment:
|
|
57
|
+
```bash
|
|
58
|
+
eas update:list --branch {env} --limit 3
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### EAS Build (Native binary — only when `app.config.ts` or native modules change)
|
|
62
|
+
|
|
63
|
+
1. ```bash
|
|
64
|
+
eas build --platform all --non-interactive --no-wait --profile={profile}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
2. Check build status:
|
|
68
|
+
```bash
|
|
69
|
+
eas build:list --limit 5
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Backend Deployment
|
|
73
|
+
|
|
74
|
+
### Full Deploy (Serverless Framework)
|
|
75
|
+
|
|
76
|
+
1. AWS signin (discover script name from backend `package.json`):
|
|
77
|
+
```bash
|
|
78
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
79
|
+
bun run aws:signin:{env}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
2. Deploy all functions:
|
|
83
|
+
```bash
|
|
84
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
85
|
+
bun run deploy:{env}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
3. Verify (use the GraphQL URL from `.env.{environment}`):
|
|
89
|
+
```bash
|
|
90
|
+
curl -sf {graphql-url} -X POST \
|
|
91
|
+
-H "Content-Type: application/json" \
|
|
92
|
+
-d '{"query":"{ __typename }"}' \
|
|
93
|
+
-w "\nHTTP %{http_code} in %{time_total}s\n"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Single Function Deploy
|
|
97
|
+
|
|
98
|
+
Discover available function names from backend `package.json` `deploy:function:*` scripts:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
102
|
+
FUNCTION_NAME={fn} bun run deploy:function:{env}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Post-Deploy Verification
|
|
106
|
+
|
|
107
|
+
After any deployment:
|
|
108
|
+
|
|
109
|
+
1. **Health check** the deployed environment (use `ops-verify-health` skill)
|
|
110
|
+
2. **Check logs** for errors in the first 5 minutes (use `ops-check-logs` skill)
|
|
111
|
+
3. **Monitor Sentry** for new issues (use `ops-monitor-errors` skill)
|
|
112
|
+
4. **Run browser UAT smoke test** against the deployed environment (use `ops-browser-uat` skill)
|
|
113
|
+
|
|
114
|
+
Report deployment result as a table:
|
|
115
|
+
|
|
116
|
+
| Target | Environment | Method | Status | Verification |
|
|
117
|
+
|--------|-------------|--------|--------|-------------|
|
|
118
|
+
| Frontend | dev | EAS Update | SUCCESS/FAIL | URL responds |
|
|
119
|
+
| Backend | dev | Serverless | SUCCESS/FAIL | GraphQL responds |
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-monitor-errors
|
|
3
|
+
description: Monitor Sentry for unresolved errors in frontend and backend projects. Supports filtering by project, environment, and time range.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Monitor Errors
|
|
10
|
+
|
|
11
|
+
Monitor Sentry for errors in the application.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — project (`frontend`, `backend`, `all`; default: `all`) and optional time range (default: `1h`)
|
|
14
|
+
|
|
15
|
+
## Discovery
|
|
16
|
+
|
|
17
|
+
Discover Sentry configuration from:
|
|
18
|
+
1. `.sentryclirc` — org and project names
|
|
19
|
+
2. `.env.*` files — `EXPO_PUBLIC_SENTRY_DSN` for DSN
|
|
20
|
+
3. `package.json` — `@sentry/react-native` (frontend) or `@sentry/node` (backend) for project type
|
|
21
|
+
|
|
22
|
+
## Sentry CLI
|
|
23
|
+
|
|
24
|
+
### List Unresolved Issues
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
sentry-cli issues list \
|
|
28
|
+
--org {org} \
|
|
29
|
+
--project {project}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Filter by Environment
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
sentry-cli issues list \
|
|
36
|
+
--org {org} \
|
|
37
|
+
--project {project} \
|
|
38
|
+
--query "is:unresolved environment:{env}"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Post-Deploy Check (new issues since deploy)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
sentry-cli issues list \
|
|
45
|
+
--org {org} \
|
|
46
|
+
--project {project} \
|
|
47
|
+
--query "is:unresolved firstSeen:-{time}"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Where `{time}` is a Sentry duration like `1h`, `30m`, `24h`.
|
|
51
|
+
|
|
52
|
+
## Sentry API (Fallback)
|
|
53
|
+
|
|
54
|
+
If `sentry-cli` is not installed or not authenticated, use the API directly:
|
|
55
|
+
|
|
56
|
+
### List Unresolved Issues
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
curl -sf "https://sentry.io/api/0/projects/{org}/{project}/issues/?query=is:unresolved&sort=date" \
|
|
60
|
+
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" | \
|
|
61
|
+
jq '.[] | {id: .id, title: .title, count: .count, userCount: .userCount, firstSeen: .firstSeen, lastSeen: .lastSeen}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Filter by Environment
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
curl -sf "https://sentry.io/api/0/projects/{org}/{project}/issues/?query=is:unresolved+environment:{env}&sort=date" \
|
|
68
|
+
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" | \
|
|
69
|
+
jq '.[] | {id: .id, title: .title, count: .count, userCount: .userCount}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Post-Deploy Workflow
|
|
73
|
+
|
|
74
|
+
After any deployment:
|
|
75
|
+
|
|
76
|
+
1. Wait 5 minutes for errors to surface
|
|
77
|
+
2. Check for new unresolved issues in the deployed environment
|
|
78
|
+
3. Assess severity: are these new regressions or pre-existing?
|
|
79
|
+
4. Report findings with severity assessment
|
|
80
|
+
|
|
81
|
+
## Output Format
|
|
82
|
+
|
|
83
|
+
Report errors as a table:
|
|
84
|
+
|
|
85
|
+
| Issue ID | Title | Events | Users | First Seen | Severity |
|
|
86
|
+
|----------|-------|--------|-------|------------|----------|
|
|
87
|
+
| 12345 | TypeError: Cannot read property 'name' | 42 | 15 | 5m ago | HIGH |
|
|
88
|
+
| 12346 | Network request failed | 3 | 2 | 2h ago | MEDIUM |
|
|
89
|
+
|
|
90
|
+
### Severity Classification
|
|
91
|
+
|
|
92
|
+
| Severity | Criteria |
|
|
93
|
+
|----------|----------|
|
|
94
|
+
| CRITICAL | > 100 events or > 50 users in last hour |
|
|
95
|
+
| HIGH | > 10 events or > 5 users, appeared after deploy |
|
|
96
|
+
| MEDIUM | Recurring issue, < 10 events |
|
|
97
|
+
| LOW | < 3 events, no user impact |
|
|
98
|
+
|
|
99
|
+
Include summary: total unresolved issues, new since last deploy, and recommendation (proceed / investigate / rollback).
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-performance
|
|
3
|
+
description: Performance analysis for Expo + serverless backend projects. Runs Lighthouse audits, bundle size analysis, and k6 load tests.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Performance
|
|
10
|
+
|
|
11
|
+
Analyze application performance.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — analysis type (`lighthouse`, `bundle`, `k6`, `all`; default: `all`) and optional target environment
|
|
14
|
+
|
|
15
|
+
## Path Convention
|
|
16
|
+
|
|
17
|
+
- **Frontend**: Current project directory (`.`)
|
|
18
|
+
- **Backend**: `${BACKEND_DIR:-../backend-v2}` — set `BACKEND_DIR` in `.claude/settings.local.json` if your backend is elsewhere
|
|
19
|
+
|
|
20
|
+
## Discovery
|
|
21
|
+
|
|
22
|
+
1. Read frontend `package.json` for `lighthouse:check`, `export:web`, `analyze:bundle` scripts
|
|
23
|
+
2. Read backend `package.json` for `k6:*` scripts
|
|
24
|
+
3. Read `e2e/constants.ts` or `.env.*` files for environment URLs
|
|
25
|
+
|
|
26
|
+
## Lighthouse Audit
|
|
27
|
+
|
|
28
|
+
### Against Local
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx lighthouse http://localhost:8081 \
|
|
32
|
+
--output=json \
|
|
33
|
+
--output-path=./lighthouse-local.json \
|
|
34
|
+
--chrome-flags='--headless --no-sandbox'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Against Deployed Environment
|
|
38
|
+
|
|
39
|
+
Discover frontend URLs from `e2e/constants.ts` or `.env.*` files:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx lighthouse https://{env_url} \
|
|
43
|
+
--output=json \
|
|
44
|
+
--output-path=./lighthouse-{env}.json \
|
|
45
|
+
--chrome-flags='--headless --no-sandbox'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### LHCI (Lighthouse CI — uses project config)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
bun run lighthouse:check
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Parse Lighthouse Results
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cat lighthouse-{env}.json | jq '{
|
|
58
|
+
performance: .categories.performance.score,
|
|
59
|
+
accessibility: .categories.accessibility.score,
|
|
60
|
+
bestPractices: .categories["best-practices"].score,
|
|
61
|
+
seo: .categories.seo.score,
|
|
62
|
+
fcp: .audits["first-contentful-paint"].displayValue,
|
|
63
|
+
lcp: .audits["largest-contentful-paint"].displayValue,
|
|
64
|
+
tbt: .audits["total-blocking-time"].displayValue,
|
|
65
|
+
cls: .audits["cumulative-layout-shift"].displayValue,
|
|
66
|
+
si: .audits["speed-index"].displayValue
|
|
67
|
+
}'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Bundle Analysis
|
|
71
|
+
|
|
72
|
+
### Full Analysis (export + source-map-explorer)
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
bun run export:web && bun run analyze:bundle
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Quick Size Check
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
bun run export:web
|
|
82
|
+
echo "=== Total Bundle Size ==="
|
|
83
|
+
du -sh dist/
|
|
84
|
+
echo ""
|
|
85
|
+
echo "=== Largest JS Files ==="
|
|
86
|
+
find dist -name "*.js" -exec ls -lhS {} + 2>/dev/null | head -20
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## k6 Load Tests
|
|
90
|
+
|
|
91
|
+
Discover available k6 scripts from the backend `package.json` (matching `k6:*`).
|
|
92
|
+
|
|
93
|
+
### Smoke Test (minimal load, verify endpoints work)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
97
|
+
bun run k6:smoke
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Load Test (normal traffic simulation)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
104
|
+
bun run k6:load
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Stress Test (push beyond normal capacity)
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
111
|
+
bun run k6:stress
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Spike Test (sudden traffic burst)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
118
|
+
bun run k6:spike
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Docker-based k6 (no local k6 install needed)
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
cd "${BACKEND_DIR:-../backend-v2}"
|
|
125
|
+
bun run k6:docker:smoke
|
|
126
|
+
bun run k6:docker:load
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Output Format
|
|
130
|
+
|
|
131
|
+
### Lighthouse Scores
|
|
132
|
+
|
|
133
|
+
| Metric | Score | Rating |
|
|
134
|
+
|--------|-------|--------|
|
|
135
|
+
| Performance | 0.85 | GOOD |
|
|
136
|
+
| Accessibility | 0.92 | GOOD |
|
|
137
|
+
| Best Practices | 0.88 | GOOD |
|
|
138
|
+
| SEO | 0.95 | GOOD |
|
|
139
|
+
|
|
140
|
+
### Core Web Vitals
|
|
141
|
+
|
|
142
|
+
| Metric | Value | Threshold | Status |
|
|
143
|
+
|--------|-------|-----------|--------|
|
|
144
|
+
| FCP (First Contentful Paint) | 1.2s | < 1.8s | PASS |
|
|
145
|
+
| LCP (Largest Contentful Paint) | 2.1s | < 2.5s | PASS |
|
|
146
|
+
| TBT (Total Blocking Time) | 150ms | < 200ms | PASS |
|
|
147
|
+
| CLS (Cumulative Layout Shift) | 0.05 | < 0.1 | PASS |
|
|
148
|
+
|
|
149
|
+
### Bundle Size
|
|
150
|
+
|
|
151
|
+
| Category | Size | Notes |
|
|
152
|
+
|----------|------|-------|
|
|
153
|
+
| Total dist/ | 4.2 MB | |
|
|
154
|
+
| Largest chunk | 1.1 MB | vendor.js |
|
|
155
|
+
|
|
156
|
+
### k6 Results
|
|
157
|
+
|
|
158
|
+
| Metric | Value |
|
|
159
|
+
|--------|-------|
|
|
160
|
+
| Requests/sec | 450 |
|
|
161
|
+
| Avg response time | 120ms |
|
|
162
|
+
| p95 response time | 350ms |
|
|
163
|
+
| Error rate | 0.1% |
|
|
164
|
+
|
|
165
|
+
Include recommendations for any metrics that fall below thresholds.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-run-local
|
|
3
|
+
description: Manage the local development environment for Expo + serverless backend projects. Supports start, stop, restart, and status for the full stack or individual services.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Run Local
|
|
10
|
+
|
|
11
|
+
Manage the local development environment.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — `start`, `stop`, `restart`, `status`, `start-frontend`, `start-backend` (default: `start`)
|
|
14
|
+
|
|
15
|
+
## Path Convention
|
|
16
|
+
|
|
17
|
+
- **Frontend**: Current project directory (`.`)
|
|
18
|
+
- **Backend**: `${BACKEND_DIR:-../backend-v2}` — set `BACKEND_DIR` in `.claude/settings.local.json` if your backend is elsewhere
|
|
19
|
+
|
|
20
|
+
## Prerequisites (run before any operation)
|
|
21
|
+
|
|
22
|
+
1. Verify backend directory exists:
|
|
23
|
+
```bash
|
|
24
|
+
BACKEND_DIR="${BACKEND_DIR:-../backend-v2}"
|
|
25
|
+
test -d "$BACKEND_DIR" && echo "Backend dir OK: $BACKEND_DIR" || echo "ERROR: Backend dir not found at $BACKEND_DIR — set BACKEND_DIR"
|
|
26
|
+
```
|
|
27
|
+
2. Check port availability:
|
|
28
|
+
```bash
|
|
29
|
+
lsof -i :8081 2>/dev/null | grep LISTEN
|
|
30
|
+
lsof -i :3000 2>/dev/null | grep LISTEN
|
|
31
|
+
```
|
|
32
|
+
3. Verify bun is installed:
|
|
33
|
+
```bash
|
|
34
|
+
which bun && bun --version
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Discovery
|
|
38
|
+
|
|
39
|
+
Read the frontend `package.json` to find available start scripts (e.g., `start:local`, `start:dev`, `start:staging`). Read the backend `package.json` to find backend start scripts (e.g., `start:local`, `start:dev`).
|
|
40
|
+
|
|
41
|
+
## Operations
|
|
42
|
+
|
|
43
|
+
### start (full stack)
|
|
44
|
+
|
|
45
|
+
Start both backend and frontend for local development.
|
|
46
|
+
|
|
47
|
+
1. **Start backend** (background):
|
|
48
|
+
```bash
|
|
49
|
+
cd "${BACKEND_DIR:-../backend-v2}" && IS_OFFLINE=true bun run start:local
|
|
50
|
+
```
|
|
51
|
+
Run this in the background using the Bash tool with `run_in_background: true`.
|
|
52
|
+
|
|
53
|
+
2. **Wait for backend** (up to 30 seconds):
|
|
54
|
+
```bash
|
|
55
|
+
for i in $(seq 1 30); do
|
|
56
|
+
curl -sf http://localhost:3000/graphql -X POST \
|
|
57
|
+
-H "Content-Type: application/json" \
|
|
58
|
+
-d '{"query":"{ __typename }"}' > /dev/null 2>&1 && echo "Backend ready" && break
|
|
59
|
+
sleep 1
|
|
60
|
+
done
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3. **Start frontend** (background):
|
|
64
|
+
```bash
|
|
65
|
+
bun run start:local
|
|
66
|
+
```
|
|
67
|
+
Run this in the background using the Bash tool with `run_in_background: true`.
|
|
68
|
+
|
|
69
|
+
4. **Verify frontend** (up to 60 seconds — Metro bundler can be slow):
|
|
70
|
+
```bash
|
|
71
|
+
for i in $(seq 1 60); do
|
|
72
|
+
curl -sf http://localhost:8081 > /dev/null 2>&1 && echo "Frontend ready" && break
|
|
73
|
+
sleep 1
|
|
74
|
+
done
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
5. Report status table.
|
|
78
|
+
|
|
79
|
+
### start-frontend (frontend only, pointing at remote backend)
|
|
80
|
+
|
|
81
|
+
Use when the backend is already deployed and you only need the frontend.
|
|
82
|
+
|
|
83
|
+
1. ```bash
|
|
84
|
+
bun run start:dev
|
|
85
|
+
```
|
|
86
|
+
Run in background.
|
|
87
|
+
|
|
88
|
+
2. Verify:
|
|
89
|
+
```bash
|
|
90
|
+
for i in $(seq 1 60); do
|
|
91
|
+
curl -sf http://localhost:8081 > /dev/null 2>&1 && echo "Frontend ready" && break
|
|
92
|
+
sleep 1
|
|
93
|
+
done
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### start-backend (backend only)
|
|
97
|
+
|
|
98
|
+
1. Check AWS credentials (discover profile from backend `package.json` `aws:signin:*` scripts):
|
|
99
|
+
```bash
|
|
100
|
+
aws sts get-caller-identity --profile {aws-profile} 2>/dev/null
|
|
101
|
+
```
|
|
102
|
+
If expired, run the backend's `aws:signin:{env}` script.
|
|
103
|
+
|
|
104
|
+
2. Start:
|
|
105
|
+
```bash
|
|
106
|
+
cd "${BACKEND_DIR:-../backend-v2}" && IS_OFFLINE=true bun run start:local
|
|
107
|
+
```
|
|
108
|
+
Run in background.
|
|
109
|
+
|
|
110
|
+
3. Verify:
|
|
111
|
+
```bash
|
|
112
|
+
for i in $(seq 1 30); do
|
|
113
|
+
curl -sf http://localhost:3000/graphql -X POST \
|
|
114
|
+
-H "Content-Type: application/json" \
|
|
115
|
+
-d '{"query":"{ __typename }"}' > /dev/null 2>&1 && echo "Backend ready" && break
|
|
116
|
+
sleep 1
|
|
117
|
+
done
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### stop
|
|
121
|
+
|
|
122
|
+
Kill all local services.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Kill frontend (Metro bundler)
|
|
126
|
+
lsof -ti :8081 | xargs kill -9 2>/dev/null || echo "No frontend process on :8081"
|
|
127
|
+
|
|
128
|
+
# Kill backend (Serverless Offline)
|
|
129
|
+
lsof -ti :3000 | xargs kill -9 2>/dev/null || echo "No backend process on :3000"
|
|
130
|
+
|
|
131
|
+
# Stop Docker if running
|
|
132
|
+
cd "${BACKEND_DIR:-../backend-v2}" && docker compose down 2>/dev/null || true
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### restart
|
|
136
|
+
|
|
137
|
+
1. Run **stop** (above).
|
|
138
|
+
2. Wait 2 seconds: `sleep 2`
|
|
139
|
+
3. Run **start** (above).
|
|
140
|
+
4. Verify both services respond.
|
|
141
|
+
|
|
142
|
+
### status
|
|
143
|
+
|
|
144
|
+
Check what is currently running and responsive.
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
echo "=== Port Check ==="
|
|
148
|
+
echo -n "Frontend :8081 — "; lsof -i :8081 2>/dev/null | grep LISTEN > /dev/null && echo "LISTENING" || echo "NOT LISTENING"
|
|
149
|
+
echo -n "Backend :3000 — "; lsof -i :3000 2>/dev/null | grep LISTEN > /dev/null && echo "LISTENING" || echo "NOT LISTENING"
|
|
150
|
+
|
|
151
|
+
echo ""
|
|
152
|
+
echo "=== Health Check ==="
|
|
153
|
+
echo -n "Frontend :8081 — "; curl -sf -o /dev/null -w "%{http_code}" http://localhost:8081 2>/dev/null || echo "UNREACHABLE"
|
|
154
|
+
echo -n "Backend :3000 — "; curl -sf -o /dev/null -w "%{http_code}" http://localhost:3000/graphql -X POST -H "Content-Type: application/json" -d '{"query":"{ __typename }"}' 2>/dev/null || echo "UNREACHABLE"
|
|
155
|
+
|
|
156
|
+
echo ""
|
|
157
|
+
echo "=== Docker ==="
|
|
158
|
+
docker compose -f "${BACKEND_DIR:-../backend-v2}/compose.yaml" ps 2>/dev/null || echo "No Docker services running"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Report results as a table:
|
|
162
|
+
|
|
163
|
+
| Service | Port | Listening | Responsive |
|
|
164
|
+
|---------|------|-----------|------------|
|
|
165
|
+
| Frontend (Metro) | 8081 | YES/NO | YES/NO |
|
|
166
|
+
| Backend (Serverless Offline) | 3000 | YES/NO | YES/NO |
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ops-verify-health
|
|
3
|
+
description: Health check all services across environments. Checks frontend URLs, backend GraphQL endpoints, and reports response times.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ops: Verify Health
|
|
10
|
+
|
|
11
|
+
Health check all services across environments.
|
|
12
|
+
|
|
13
|
+
**Argument**: `$ARGUMENTS` — environment(s) to check (default: `all`). Options: `local`, `dev`, `staging`, `production`, `all`
|
|
14
|
+
|
|
15
|
+
## Discovery
|
|
16
|
+
|
|
17
|
+
Read these files to build the environment URL table:
|
|
18
|
+
|
|
19
|
+
1. `e2e/constants.ts` — frontend URLs per environment
|
|
20
|
+
2. `.env.localhost`, `.env.development`, `.env.staging`, `.env.production` — `EXPO_PUBLIC_GRAPHQL_BASE_URL` for backend GraphQL URLs
|
|
21
|
+
|
|
22
|
+
## Health Checks
|
|
23
|
+
|
|
24
|
+
For each environment, run these checks:
|
|
25
|
+
|
|
26
|
+
### Frontend Check
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -sf -o /dev/null -w "HTTP %{http_code} in %{time_total}s" {frontend_url}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Verify the response contains Expo/React markers:
|
|
33
|
+
```bash
|
|
34
|
+
curl -sf {frontend_url} | head -20
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Backend GraphQL Check
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
curl -sf {graphql_url} -X POST \
|
|
41
|
+
-H "Content-Type: application/json" \
|
|
42
|
+
-d '{"query":"{ __typename }"}' \
|
|
43
|
+
-w "\nHTTP %{http_code} in %{time_total}s\n"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### GraphQL Introspection (detailed check)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -sf {graphql_url} -X POST \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d '{"query":"{ __schema { queryType { name } } }"}' \
|
|
52
|
+
-w "\nHTTP %{http_code} in %{time_total}s\n"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Full Health Check Script
|
|
56
|
+
|
|
57
|
+
Run all checks for the specified environment(s):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
check_env() {
|
|
61
|
+
local ENV=$1
|
|
62
|
+
local FE_URL=$2
|
|
63
|
+
local BE_URL=$3
|
|
64
|
+
|
|
65
|
+
echo "=== $ENV ==="
|
|
66
|
+
|
|
67
|
+
# Frontend
|
|
68
|
+
FE_STATUS=$(curl -sf -o /dev/null -w "%{http_code}" --max-time 10 "$FE_URL" 2>/dev/null || echo "000")
|
|
69
|
+
FE_TIME=$(curl -sf -o /dev/null -w "%{time_total}" --max-time 10 "$FE_URL" 2>/dev/null || echo "timeout")
|
|
70
|
+
echo "Frontend: HTTP $FE_STATUS ($FE_TIME s)"
|
|
71
|
+
|
|
72
|
+
# Backend
|
|
73
|
+
BE_RESULT=$(curl -sf --max-time 10 "$BE_URL" -X POST \
|
|
74
|
+
-H "Content-Type: application/json" \
|
|
75
|
+
-d '{"query":"{ __typename }"}' \
|
|
76
|
+
-w "\n%{http_code} %{time_total}" 2>/dev/null || echo -e "\n000 timeout")
|
|
77
|
+
BE_STATUS=$(echo "$BE_RESULT" | tail -1 | awk '{print $1}')
|
|
78
|
+
BE_TIME=$(echo "$BE_RESULT" | tail -1 | awk '{print $2}')
|
|
79
|
+
echo "Backend: HTTP $BE_STATUS ($BE_TIME s)"
|
|
80
|
+
echo ""
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## EAS Update Status
|
|
85
|
+
|
|
86
|
+
Check the latest OTA updates deployed to each branch:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
eas update:list --branch {env} --limit 3
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Output Format
|
|
93
|
+
|
|
94
|
+
Report results as a table:
|
|
95
|
+
|
|
96
|
+
| Service | Environment | Status | Response Time | Details |
|
|
97
|
+
|---------|-------------|--------|---------------|---------|
|
|
98
|
+
| Frontend | dev | UP (200) | 0.45s | HTML contains React root |
|
|
99
|
+
| Backend | dev | UP (200) | 0.32s | GraphQL responds `__typename` |
|
|
100
|
+
|
|
101
|
+
Flag any service with status != 200 or response time > 5s as a concern.
|
package/package.json
CHANGED
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@isaacs/brace-expansion": "^5.0.1"
|
|
90
90
|
},
|
|
91
91
|
"name": "@codyswann/lisa",
|
|
92
|
-
"version": "1.
|
|
92
|
+
"version": "1.41.0",
|
|
93
93
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
94
94
|
"main": "dist/index.js",
|
|
95
95
|
"bin": {
|