eas-cli 20.2.0 → 20.4.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.
Files changed (47) hide show
  1. package/README.md +225 -110
  2. package/build/commandUtils/new/templates/AGENTS.md +25 -146
  3. package/build/commandUtils/new/templates/CLAUDE.md +1 -9
  4. package/build/commandUtils/posthog.d.ts +4 -0
  5. package/build/commandUtils/posthog.js +23 -0
  6. package/build/commands/account/audit.d.ts +17 -0
  7. package/build/commands/account/audit.js +112 -0
  8. package/build/commands/integrations/posthog/connect.d.ts +27 -0
  9. package/build/commands/integrations/posthog/connect.js +432 -0
  10. package/build/commands/integrations/posthog/dashboard.d.ts +13 -0
  11. package/build/commands/integrations/posthog/dashboard.js +66 -0
  12. package/build/commands/integrations/posthog/disconnect.d.ts +14 -0
  13. package/build/commands/integrations/posthog/disconnect.js +80 -0
  14. package/build/commands/observe/session.d.ts +18 -0
  15. package/build/commands/observe/session.js +65 -0
  16. package/build/commands/update/view.d.ts +7 -0
  17. package/build/commands/update/view.js +30 -3
  18. package/build/graphql/generated.d.ts +468 -2
  19. package/build/graphql/generated.js +28 -4
  20. package/build/graphql/mutations/PostHogMutation.d.ts +8 -0
  21. package/build/graphql/mutations/PostHogMutation.js +55 -0
  22. package/build/graphql/queries/AuditLogQuery.d.ts +6 -0
  23. package/build/graphql/queries/AuditLogQuery.js +57 -0
  24. package/build/graphql/queries/DeviceRunSessionQuery.js +1 -0
  25. package/build/graphql/queries/PostHogQuery.d.ts +6 -0
  26. package/build/graphql/queries/PostHogQuery.js +49 -0
  27. package/build/graphql/types/AuditLog.d.ts +1 -0
  28. package/build/graphql/types/AuditLog.js +18 -0
  29. package/build/graphql/types/Observe.js +1 -0
  30. package/build/graphql/types/PostHogConnection.d.ts +7 -0
  31. package/build/graphql/types/PostHogConnection.js +30 -0
  32. package/build/observe/fetchCustomEvents.d.ts +2 -2
  33. package/build/observe/fetchCustomEvents.js +2 -2
  34. package/build/observe/fetchEvents.d.ts +4 -3
  35. package/build/observe/fetchEvents.js +4 -3
  36. package/build/observe/fetchSessions.d.ts +51 -0
  37. package/build/observe/fetchSessions.js +86 -0
  38. package/build/observe/formatEvents.d.ts +1 -0
  39. package/build/observe/formatEvents.js +1 -0
  40. package/build/observe/formatSessions.d.ts +15 -0
  41. package/build/observe/formatSessions.js +100 -0
  42. package/build/simulator/utils.js +28 -5
  43. package/build/update/getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync.js +23 -26
  44. package/build/user/SessionManager.d.ts +1 -22
  45. package/build/user/SessionManager.js +7 -89
  46. package/oclif.manifest.json +1583 -1108
  47. package/package.json +7 -3
@@ -1,162 +1,41 @@
1
- # AGENTS.md
2
-
3
- ## Project Overview
4
-
5
1
  This is an Expo/React Native mobile application. Prioritize mobile-first patterns, performance, and cross-platform compatibility.
6
2
 
7
- ## Documentation Resources
8
-
9
- When working on this project, **always consult the official Expo documentation** available at:
10
-
11
- - **https://docs.expo.dev/llms.txt** - Index of all available documentation files
12
- - **https://docs.expo.dev/llms-full.txt** - Complete Expo documentation including Expo Router, Expo Modules API, development process
13
- - **https://docs.expo.dev/llms-eas.txt** - Complete EAS (Expo Application Services) documentation
14
- - **https://docs.expo.dev/llms-sdk.txt** - Complete Expo SDK documentation
15
- - **https://reactnative.dev/docs/getting-started** - Complete React Native documentation
16
-
17
- These documentation files are specifically formatted for AI agents and should be your **primary reference** for:
3
+ ## Expo has changed — do not trust your training data
18
4
 
19
- - Expo APIs and best practices
20
- - Expo Router navigation patterns
21
- - EAS Build, Submit, and Update workflows
22
- - Expo SDK modules and their usage
23
- - Development and deployment processes
5
+ Expo ships breaking changes every SDK release. APIs you remember are likely renamed, moved, or removed. Before writing any code that touches an Expo, EAS, or React Native API:
24
6
 
25
- ## Project Structure
7
+ 1. Read the major version of the `expo` package in `package.json`.
8
+ 2. Fetch the matching versioned docs: `https://docs.expo.dev/versions/v<major>.0.0/`
9
+ 3. For anything else, fetch https://docs.expo.dev/llms.txt — an index of all Expo docs with corrections to common LLM misconceptions. Follow its links to the specific page you need; never answer from memory.
26
10
 
27
- ```
28
- /
29
- ├── app/ # Expo Router file-based routing
30
- │ ├── (tabs)/ # Tab-based navigation screens
31
- │ │ ├── index.tsx # Home screen
32
- │ │ ├── explore.tsx # Explore screen
33
- │ │ └── _layout.tsx # Tabs layout
34
- │ ├── _layout.tsx # Root layout with theme provider
35
- │ └── modal.tsx # Modal screen example
36
- ├── components/ # Reusable React components
37
- │ ├── ui/ # UI primitives (IconSymbol, Collapsible)
38
- │ └── ... # Feature components (themed, haptic, parallax)
39
- ├── constants/ # App-wide constants (theme, colors)
40
- ├── hooks/ # Custom React hooks (color scheme, theme)
41
- ├── assets/ # Static assets (images, fonts)
42
- ├── scripts/ # Utility scripts (reset-project)
43
- ├── .eas/workflows/ # EAS Workflows (CI/CD automation)
44
- ├── app.json # Expo configuration
45
- ├── eas.json # EAS Build/Submit configuration
46
- └── package.json # Dependencies and scripts
47
- ```
48
-
49
- ## Essential Commands
11
+ ## Commands
50
12
 
51
- ### Development
13
+ Use `bunx` instead of `npx` if the project uses bun (`bun.lock` present).
52
14
 
53
15
  ```bash
54
- npx expo start # Start dev server
55
- npx expo start --clear # Clear cache and start dev server
56
- npx expo install <package> # Install packages with compatible versions
57
- npx expo install --check # Check which installed packages need to be updated
58
- npx expo install --fix # Automatically update any invalid package versions
59
- npm run development-builds # Create development builds (workflow)
60
- npm run reset-project # Reset to blank template
16
+ npx expo install <package> # ALWAYS use instead of npm/yarn/pnpm/bun add — resolves SDK-compatible versions
17
+ npx expo start # start the dev server
18
+ npx expo lint # lint
19
+ npx tsc --noEmit # typecheck
20
+ npx expo-doctor # diagnose dependency and config issues
21
+ npx expo install --fix # fix incompatible package versions
61
22
  ```
62
23
 
63
- ### Building & Testing
64
-
65
- ```bash
66
- npx expo doctor # Check project health and dependencies
67
- npx expo lint # Run ESLint
68
- npm run draft # Publish preview update and website (workflow)
69
- ```
70
-
71
- ### Production
72
-
73
- ```bash
74
- npx eas-cli@latest build --platform ios -s # Use EAS to build for iOS platform and submit to App Store
75
- npx eas-cli@latest build --platform android -s # Use EAS to build for Android platform and submit to Google Play Store
76
- npm run deploy # Deploy to production (workflow)
77
- ```
78
-
79
- ## Development Guidelines
80
-
81
- ### Code Style & Standards
82
-
83
- - **TypeScript First**: Use TypeScript for all new code with strict type checking
84
- - **Naming Conventions**: Use meaningful, descriptive names for variables, functions, and components
85
- - **Self-Documenting Code**: Write clear, readable code that explains itself; only add comments for complex business logic or design decisions
86
- - **React 19 Patterns**: Follow modern React patterns including:
87
- - Function components with hooks
88
- - Enable React Compiler
89
- - Proper dependency arrays in useEffect
90
- - Memoization when appropriate (useMemo, useCallback)
91
- - Error boundaries for better error handling
92
-
93
- ### Navigation & Routing
94
-
95
- - Use **Expo Router** for all navigation
96
- - Import `Link`, `router`, and `useLocalSearchParams` from `expo-router`
97
- - Docs: https://docs.expo.dev/router/introduction/
98
-
99
- ### Recommended Libraries
100
-
101
- - **Navigation**: `expo-router` for navigation
102
- - **Images**: `expo-image` for optimized image handling and caching
103
- - **Animations**: `react-native-reanimated` for performant animations on native thread
104
- - **Gestures**: `react-native-gesture-handler` for native gesture recognition
105
- - **Storage**: Use `expo-sqlite` for persistent storage, `expo-sqlite/kv-store` for simple key-value storage
106
-
107
- ## Debugging & Development Tools
108
-
109
- ### DevTools Integration
110
-
111
- - **React Native DevTools**: Use MCP `open_devtools` command to launch debugging tools
112
- - **Network Inspection**: Monitor API calls and network requests in DevTools
113
- - **Element Inspector**: Debug component hierarchy and styles
114
- - **Performance Profiler**: Identify performance bottlenecks
115
- - **Logging**: Use `console.log` for debugging (remove before production), `console.warn` for deprecation notices, `console.error` for actual errors, and implement error boundaries for production error handling
116
-
117
- ### Testing & Quality Assurance
118
-
119
- #### Automated Testing with MCP Tools
120
-
121
- Developers can configure the Expo MCP server with the following doc: https://docs.expo.dev/eas/ai/mcp/
122
-
123
- - **Component Testing**: Add `testID` props to components for automation
124
- - **Visual Testing**: Use MCP `automation_take_screenshot` to verify UI appearance
125
- - **Interaction Testing**: Use MCP `automation_tap_by_testid` to simulate user interactions
126
- - **View Verification**: Use MCP `automation_find_view_by_testid` to validate component rendering
127
-
128
- ## EAS Workflows CI/CD
129
-
130
- This project is pre-configured with **EAS Workflows** for automating development and release processes. Workflows are defined in `.eas/workflows/` directory.
131
-
132
- When working with EAS Workflows, **always refer to**:
133
-
134
- - https://docs.expo.dev/eas/workflows/ for workflow examples
135
- - The `.eas/workflows/` directory for existing workflow configurations
136
- - You can check that a workflow YAML is valid using the workflows schema: https://exp.host/--/api/v2/workflows/schema
137
-
138
- ### Build Profiles (eas.json)
139
-
140
- - **development**: Development builds with dev client
141
- - **development-simulator**: Development builds for iOS simulator
142
- - **preview**: Internal distribution preview builds
143
- - **production**: Production builds with auto-increment
144
-
145
- ## Troubleshooting
146
-
147
- ### Expo Go Errors & Development Builds
24
+ Run lint and typecheck before declaring any task done.
148
25
 
149
- If there are errors in **Expo Go** or the project is not running, create a **development build**. **Expo Go** is a sandbox environment with a limited set of native modules. To create development builds, run `eas build:dev`. Additionally, after installing new packages or adding config plugins, new development builds are often required.
26
+ ## Navigation & Routing
150
27
 
151
- ## AI Agent Instructions
28
+ - Use **Expo Router** for all navigation. Routes live in `src/app/` — every file there is a screen, `_layout.tsx` files define navigators. Keep non-route code (components, hooks, utils) outside `src/app/`.
29
+ - Import `Link`, `router`, and `useLocalSearchParams` from `expo-router`.
30
+ - Docs: https://docs.expo.dev/router/introduction.md
152
31
 
153
- When working on this project:
32
+ ## Building with EAS
154
33
 
155
- 1. **Always start by consulting the appropriate documentation**:
156
- - For general Expo questions: https://docs.expo.dev/llms-full.txt
157
- - For EAS/deployment questions: https://docs.expo.dev/llms-eas.txt
158
- - For SDK/API questions: https://docs.expo.dev/llms-sdk.txt
34
+ Use EAS to build, sign, and submit the app in the cloud (`eas build`, `eas submit`) and to ship over-the-air updates (`eas update`) — no local Xcode or Android Studio required. Run EAS CLI as `bunx eas-cli <command>` in Bun projects, or `npx eas-cli@latest <command>` otherwise; substitute that for bare `eas` in docs examples.
35
+ Docs: https://docs.expo.dev/eas/index.md
159
36
 
160
- 2. **Understand before implementing**: Read the relevant docs section before writing code
37
+ ## Rules
161
38
 
162
- 3. **Follow existing patterns**: Look at existing components and screens for patterns to follow
39
+ - If `ios/` and `android/` directories do not exist, they are generated (Continuous Native Generation). Never create or edit them by hand configure native behavior in `app.json` and config plugins.
40
+ - Expo Go only includes its bundled native modules. After adding a library with native code, the app needs a development build: `npx expo run:ios|android` locally, or `eas build --profile development`.
41
+ - Prefer recommended Expo modules over third-party libraries, and check your available skills before adding dependencies. Docs: https://docs.expo.dev/versions/latest/index.md
@@ -1,9 +1 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- **Note**: This project uses `AGENTS.md` files for detailed guidance.
6
-
7
- ## Primary Reference
8
-
9
- Please see `AGENTS.md` in this same directory for the main project documentation and guidance.
1
+ @AGENTS.md
@@ -0,0 +1,4 @@
1
+ import { PostHogProjectData } from '../graphql/types/PostHogConnection';
2
+ export declare function getPostHogProjectDashboardUrl(project: PostHogProjectData): string;
3
+ export declare function formatPostHogProject(project: PostHogProjectData): string;
4
+ export declare function logNoPostHogProject(projectName: string): void;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPostHogProjectDashboardUrl = getPostHogProjectDashboardUrl;
4
+ exports.formatPostHogProject = formatPostHogProject;
5
+ exports.logNoPostHogProject = logNoPostHogProject;
6
+ const tslib_1 = require("tslib");
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const log_1 = tslib_1.__importStar(require("../log"));
9
+ function getPostHogProjectDashboardUrl(project) {
10
+ const host = project.posthogHost.replace(/\/$/, '');
11
+ return `${host}/project/${encodeURIComponent(project.posthogProjectIdentifier)}`;
12
+ }
13
+ function formatPostHogProject(project) {
14
+ return [
15
+ `${chalk_1.default.bold('Name')}: ${project.posthogProjectName}`,
16
+ `${chalk_1.default.bold('Host')}: ${project.posthogHost}`,
17
+ `${chalk_1.default.bold('Region')}: ${project.posthogOrganizationConnection.posthogRegion}`,
18
+ `${chalk_1.default.bold('Dashboard')}: ${(0, log_1.link)(getPostHogProjectDashboardUrl(project), { dim: false })}`,
19
+ ].join('\n');
20
+ }
21
+ function logNoPostHogProject(projectName) {
22
+ log_1.default.warn(`No PostHog project is linked to Expo app ${chalk_1.default.bold(projectName)} on EAS.`);
23
+ }
@@ -0,0 +1,17 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ export default class AccountAudit extends EasCommand {
3
+ static description: string;
4
+ static args: {
5
+ ACCOUNT_NAME: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
6
+ };
7
+ static flags: {
8
+ 'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined>;
11
+ after: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ };
13
+ static contextDefinition: {
14
+ loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
15
+ };
16
+ runAsync(): Promise<void>;
17
+ }
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
6
+ const flags_1 = require("../../commandUtils/flags");
7
+ const pagination_1 = require("../../commandUtils/pagination");
8
+ const AuditLogQuery_1 = require("../../graphql/queries/AuditLogQuery");
9
+ const log_1 = tslib_1.__importDefault(require("../../log"));
10
+ const ora_1 = require("../../ora");
11
+ const prompts_1 = require("../../prompts");
12
+ const json_1 = require("../../utils/json");
13
+ const renderTextTable_1 = tslib_1.__importDefault(require("../../utils/renderTextTable"));
14
+ const AUDIT_LOGS_LIMIT = 50;
15
+ class AccountAudit extends EasCommand_1.default {
16
+ static description = 'view the audit logs for an account';
17
+ static args = {
18
+ ACCOUNT_NAME: core_1.Args.string({
19
+ description: 'Account name to view audit logs for. If not provided, the account will be selected interactively (or defaults to the only account if there is just one)',
20
+ }),
21
+ };
22
+ static flags = {
23
+ limit: (0, pagination_1.getLimitFlagWithCustomValues)({ defaultTo: AUDIT_LOGS_LIMIT, limit: 100 }),
24
+ after: core_1.Flags.string({
25
+ description: 'Cursor for pagination. Use the endCursor from a previous query to fetch the next page.',
26
+ }),
27
+ ...flags_1.EasJsonOnlyFlag,
28
+ ...flags_1.EASNonInteractiveFlag,
29
+ };
30
+ static contextDefinition = {
31
+ ...this.ContextOptions.LoggedIn,
32
+ };
33
+ async runAsync() {
34
+ const { args: { ACCOUNT_NAME: accountName }, flags: { limit, after, json: jsonFlag, 'non-interactive': nonInteractive }, } = await this.parse(AccountAudit);
35
+ const json = jsonFlag || nonInteractive;
36
+ if (json) {
37
+ (0, json_1.enableJsonOutput)();
38
+ }
39
+ const { loggedIn: { graphqlClient, actor }, } = await this.getContextAsync(AccountAudit, { nonInteractive });
40
+ const pageSize = limit ?? AUDIT_LOGS_LIMIT;
41
+ let targetAccount;
42
+ const availableAccounts = actor.accounts.map(a => a.name).join(', ');
43
+ if (accountName) {
44
+ const found = actor.accounts.find(a => a.name === accountName);
45
+ if (!found) {
46
+ throw new Error(`Account "${accountName}" not found or you don't have access. Available accounts: ${availableAccounts}`);
47
+ }
48
+ targetAccount = found;
49
+ }
50
+ else if (nonInteractive) {
51
+ throw new Error('ACCOUNT_NAME argument must be provided when running in `--non-interactive` mode.');
52
+ }
53
+ else if (actor.accounts.length === 1) {
54
+ targetAccount = actor.accounts[0];
55
+ }
56
+ else {
57
+ targetAccount = await (0, prompts_1.selectAsync)('Select account to view audit logs for:', actor.accounts.map(account => ({
58
+ title: account.name,
59
+ value: account,
60
+ })));
61
+ }
62
+ if (json) {
63
+ const spinner = (0, ora_1.ora)(`Fetching audit logs for account ${targetAccount.name}`).start();
64
+ try {
65
+ const connection = await AuditLogQuery_1.AuditLogQuery.getAllForAccountAsync(graphqlClient, targetAccount.id, {
66
+ first: pageSize,
67
+ after,
68
+ });
69
+ spinner.stop();
70
+ (0, json_1.printJsonOnlyOutput)({
71
+ auditLogs: connection.edges.map(edge => edge.node),
72
+ pageInfo: connection.pageInfo,
73
+ });
74
+ }
75
+ catch (error) {
76
+ spinner.fail(`Failed to fetch audit logs for account ${targetAccount.name}`);
77
+ throw error;
78
+ }
79
+ return;
80
+ }
81
+ let cursor = after;
82
+ do {
83
+ const spinner = (0, ora_1.ora)(`Fetching audit logs for account ${targetAccount.name}`).start();
84
+ const connection = await AuditLogQuery_1.AuditLogQuery.getAllForAccountAsync(graphqlClient, targetAccount.id, {
85
+ first: pageSize,
86
+ after: cursor,
87
+ });
88
+ spinner.stop();
89
+ const logs = connection.edges.map(edge => edge.node);
90
+ renderPageOfAuditLogs(logs);
91
+ if (!connection.pageInfo.hasNextPage) {
92
+ break;
93
+ }
94
+ cursor = connection.pageInfo.endCursor ?? undefined;
95
+ } while (cursor && (await (0, prompts_1.confirmAsync)({ message: 'Load more audit logs?' })));
96
+ }
97
+ }
98
+ exports.default = AccountAudit;
99
+ function renderPageOfAuditLogs(logs) {
100
+ if (logs.length === 0) {
101
+ log_1.default.log('No audit logs found.');
102
+ return;
103
+ }
104
+ log_1.default.log((0, renderTextTable_1.default)(['Date', 'Actor', 'Action', 'Entity', 'Message'], logs.map(log => [
105
+ new Date(log.createdAt).toLocaleString(),
106
+ log.actor?.displayName ?? 'Unknown',
107
+ log.targetEntityMutationType,
108
+ log.targetEntityTypePublicName,
109
+ log.websiteMessage,
110
+ ])));
111
+ log_1.default.addNewLineIfNone();
112
+ }
@@ -0,0 +1,27 @@
1
+ import EasCommand from '../../../commandUtils/EasCommand';
2
+ export default class IntegrationsPostHogConnect extends EasCommand {
3
+ static description: string;
4
+ static contextDefinition: {
5
+ loggedIn: import("../../../commandUtils/context/LoggedInContextField").default;
6
+ privateProjectConfig: import("../../../commandUtils/context/PrivateProjectConfigContextField").PrivateProjectConfigContextField;
7
+ };
8
+ static flags: {
9
+ region: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ 'session-replay': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
+ 'error-tracking': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ 'posthog-cli-api-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ overwrite: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ 'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ };
17
+ runAsync(): Promise<void>;
18
+ private resolveFeaturesAsync;
19
+ private resolveCliApiKeyAsync;
20
+ private resolveRegionAsync;
21
+ private installSdkPackagesAsync;
22
+ private addConfigPluginAsync;
23
+ private writeEnvLocalAsync;
24
+ private mergeEnvContent;
25
+ private upsertEasEnvVarAsync;
26
+ private printNextSteps;
27
+ }