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
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Minimal operating guide for AI coding agents in this repo.

## E2E Validation
- For changes that affect runtime inspection, memory tooling, agent workflows, or validation flows, validate end-to-end through the Expo app in `./playground`.
- Reference: `docs/e2e-playground-workflow.md`

## First Minute
- Classify the task first:
- Info-only, review, triage, docs: no code edits and no test runs unless explicitly requested.
Expand Down
44 changes: 44 additions & 0 deletions docs/e2e-playground-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# E2E Playground Workflow

This repository uses the Expo app in `./playground` as the standard harness for end-to-end checks involving `agent-device` and `agent-cdp`.

## Goal

Validate the real user flow and the runtime inspection flow together:

1. A device automation agent can operate the app reliably.
2. agent-cdp can observe the runtime side effects triggered by those actions.

## Standard Flow

1. Confirm the app opens to the single-screen button harness.
2. Verify `agent-device` can identify and tap the scenario buttons by their visible labels.
3. Connect agent-cdp to the running app session.
4. Tap `Retain 250 objects` and confirm retained memory signals increase.
5. Tap `Retain 1200 objects` and confirm the larger retained batch is visible in memory inspection output.
6. Tap `Create transient churn` and compare the result against retained-memory actions.
7. Tap `Emit console burst` and inspect the info, warning, and handled error entries in `agent-cdp` console output.
8. Tap `Run CPU hotspot` and `Run async burst` when validating trace or JS profiling commands.
9. Tap `Run network burst` when validating network capture, request summaries, bodies, or headers.
10. Tap `Log inspection payload` and inspect the emitted runtime payload with agent-cdp console or runtime tooling.
11. Tap `Clear retained batches` and confirm the store is empty in the UI and the retained-memory signal drops.

## Expected Playground Signals

The current playground exposes these signals:

1. A global store at `globalThis.__agentCdpPlayground`.
2. Retained object batches for memory inspection.
3. Transient allocation churn for comparison.
4. Structured console payloads for runtime inspection.
5. Synchronous and asynchronous CPU-heavy workloads for trace and JS profiler validation.
6. Successful and failing local HTTP requests for network inspection validation.

## Reporting

When finishing a task, include:

1. The commands you ran.
2. The device flow you exercised with `agent-device`.
3. The agent-cdp checks you performed.
4. Any blockers, flaky behavior, or verification gaps.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"private": true,
"license": "MIT",
"workspaces": [
"packages/*"
"packages/*",
"playground"
],
"scripts": {
"agent-cdp": "node packages/agent-cdp/dist/bin.js",
Expand Down
43 changes: 43 additions & 0 deletions playground/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

app-example

# generated native folders
/ios
/android
1 change: 1 addition & 0 deletions playground/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node-linker=hoisted
46 changes: 46 additions & 0 deletions playground/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"expo": {
"name": "AgentCDP",
"slug": "agent-cdp",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "agentcdp",
"userInterfaceStyle": "automatic",
"ios": {
"icon": "./assets/expo.icon",
"bundleIdentifier": "com.aitwar.agentcdp"
},
"android": {
"package": "com.aitwar.agentcdp",
"adaptiveIcon": {
"backgroundColor": "#E6F4FE",
"foregroundImage": "./assets/images/android-icon-foreground.png",
"backgroundImage": "./assets/images/android-icon-background.png",
"monochromeImage": "./assets/images/android-icon-monochrome.png"
},
"predictiveBackGestureEnabled": false
},
"web": {
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"plugins": [
"expo-router",
[
"expo-splash-screen",
{
"backgroundColor": "#208AEF",
"android": {
"image": "./assets/images/splash-icon.png",
"imageWidth": 76
}
}
]
],
"experiments": {
"typedRoutes": true,
"reactCompiler": true
}
}
}
3 changes: 3 additions & 0 deletions playground/assets/expo.icon/Assets/expo-symbol 2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/expo.icon/Assets/grid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions playground/assets/expo.icon/icon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"fill" : {
"automatic-gradient" : "extended-srgb:0.00000,0.47843,1.00000,1.00000"
},
"groups" : [
{
"layers" : [
{
"image-name" : "expo-symbol 2.svg",
"name" : "expo-symbol 2",
"position" : {
"scale" : 1,
"translation-in-points" : [
1.1008400065293245e-05,
-16.046875
]
}
},
{
"image-name" : "grid.png",
"name" : "grid"
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/expo-badge-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/expo-badge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/expo-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/logo-glow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/react-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/react-logo@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/react-logo@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/splash-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/tabIcons/explore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/tabIcons/explore@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/tabIcons/explore@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/tabIcons/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/tabIcons/home@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/tabIcons/home@3x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added playground/assets/images/tutorial-web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions playground/declarations.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module '*.module.css' {
const classes: Record<string, string>;
export default classes;
}
10 changes: 10 additions & 0 deletions playground/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// https://docs.expo.dev/guides/using-eslint/
const { defineConfig } = require('eslint/config');
const expoConfig = require("eslint-config-expo/flat");

module.exports = defineConfig([
expoConfig,
{
ignores: ["dist/*"],
}
]);
46 changes: 46 additions & 0 deletions playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "playground",
"main": "expo-router/entry",
"version": "1.0.0",
"scripts": {
"start": "expo start",
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web",
"lint": "expo lint"
},
"dependencies": {
"@react-navigation/bottom-tabs": "^7.15.5",
"@react-navigation/elements": "^2.9.10",
"@react-navigation/native": "^7.1.33",
"expo": "~55.0.24",
"expo-constants": "~55.0.16",
"expo-device": "~55.0.17",
"expo-font": "~55.0.7",
"expo-glass-effect": "~55.0.11",
"expo-image": "~55.0.10",
"expo-linking": "~55.0.15",
"expo-router": "~55.0.14",
"expo-splash-screen": "~55.0.21",
"expo-status-bar": "~55.0.6",
"expo-symbols": "~55.0.8",
"expo-system-ui": "~55.0.18",
"expo-web-browser": "~55.0.16",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-native": "0.83.6",
"react-native-gesture-handler": "~2.30.0",
"react-native-reanimated": "4.2.1",
"react-native-safe-area-context": "~5.6.2",
"react-native-screens": "~4.23.0",
"react-native-web": "~0.21.0",
"react-native-worklets": "0.7.4"
},
"devDependencies": {
"@types/react": "~19.2.2",
"eslint": "^9.0.0",
"eslint-config-expo": "~55.0.1",
"typescript": "~5.9.2"
},
"private": true
}
14 changes: 14 additions & 0 deletions playground/src/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
import { Slot } from 'expo-router';
import React from 'react';
import { useColorScheme } from 'react-native';

export default function RootLayout() {
const colorScheme = useColorScheme();

return (
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Slot />
</ThemeProvider>
);
}
Loading
Loading