@codyswann/lisa 2.111.0 → 2.112.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 (155) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  5. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  6. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  7. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  8. package/plugins/lisa-expo/.mcp.json +3 -3
  9. package/plugins/lisa-expo/THIRD-PARTY-NOTICES.md +57 -0
  10. package/plugins/lisa-expo/skills/add-app-clip/SKILL.md +280 -0
  11. package/plugins/lisa-expo/skills/add-app-clip/agents/openai.yaml +4 -0
  12. package/plugins/lisa-expo/skills/add-app-clip/references/native-module.md +96 -0
  13. package/plugins/lisa-expo/skills/building-native-ui/SKILL.md +321 -0
  14. package/plugins/lisa-expo/skills/building-native-ui/agents/openai.yaml +4 -0
  15. package/plugins/lisa-expo/skills/building-native-ui/references/animations.md +220 -0
  16. package/plugins/lisa-expo/skills/building-native-ui/references/controls.md +272 -0
  17. package/plugins/lisa-expo/skills/building-native-ui/references/form-sheet.md +253 -0
  18. package/plugins/lisa-expo/skills/building-native-ui/references/gradients.md +106 -0
  19. package/plugins/lisa-expo/skills/building-native-ui/references/icons.md +213 -0
  20. package/plugins/lisa-expo/skills/building-native-ui/references/media.md +198 -0
  21. package/plugins/lisa-expo/skills/building-native-ui/references/route-structure.md +229 -0
  22. package/plugins/lisa-expo/skills/building-native-ui/references/search.md +248 -0
  23. package/plugins/lisa-expo/skills/building-native-ui/references/storage.md +121 -0
  24. package/plugins/lisa-expo/skills/building-native-ui/references/tabs.md +433 -0
  25. package/plugins/lisa-expo/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
  26. package/plugins/lisa-expo/skills/building-native-ui/references/visual-effects.md +197 -0
  27. package/plugins/lisa-expo/skills/building-native-ui/references/webgpu-three.md +605 -0
  28. package/plugins/lisa-expo/skills/building-native-ui/references/zoom-transitions.md +158 -0
  29. package/plugins/lisa-expo/skills/eas-update-insights/SKILL.md +228 -0
  30. package/plugins/lisa-expo/skills/eas-update-insights/agents/openai.yaml +4 -0
  31. package/plugins/lisa-expo/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
  32. package/plugins/lisa-expo/skills/eas-update-insights/references/update-insights-schema.md +69 -0
  33. package/plugins/lisa-expo/skills/expo-api-routes/SKILL.md +369 -0
  34. package/plugins/lisa-expo/skills/expo-api-routes/agents/openai.yaml +4 -0
  35. package/plugins/lisa-expo/skills/expo-brownfield/SKILL.md +54 -0
  36. package/plugins/lisa-expo/skills/expo-brownfield/agents/openai.yaml +4 -0
  37. package/plugins/lisa-expo/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
  38. package/plugins/lisa-expo/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
  39. package/plugins/lisa-expo/skills/expo-brownfield/references/comparison.md +63 -0
  40. package/plugins/lisa-expo/skills/expo-brownfield/references/troubleshooting.md +88 -0
  41. package/plugins/lisa-expo/skills/expo-cicd-workflows/SKILL.md +92 -0
  42. package/plugins/lisa-expo/skills/expo-cicd-workflows/agents/openai.yaml +4 -0
  43. package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
  44. package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/package.json +11 -0
  45. package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/validate.js +85 -0
  46. package/plugins/lisa-expo/skills/expo-deployment/SKILL.md +190 -0
  47. package/plugins/lisa-expo/skills/expo-deployment/agents/openai.yaml +4 -0
  48. package/plugins/lisa-expo/skills/expo-deployment/references/app-store-metadata.md +479 -0
  49. package/plugins/lisa-expo/skills/expo-deployment/references/ios-app-store.md +355 -0
  50. package/plugins/lisa-expo/skills/expo-deployment/references/play-store.md +246 -0
  51. package/plugins/lisa-expo/skills/expo-deployment/references/testflight.md +58 -0
  52. package/plugins/lisa-expo/skills/expo-deployment/references/workflows.md +200 -0
  53. package/plugins/lisa-expo/skills/expo-dev-client/SKILL.md +164 -0
  54. package/plugins/lisa-expo/skills/expo-dev-client/agents/openai.yaml +4 -0
  55. package/plugins/lisa-expo/skills/expo-module/SKILL.md +141 -0
  56. package/plugins/lisa-expo/skills/expo-module/agents/openai.yaml +4 -0
  57. package/plugins/lisa-expo/skills/expo-module/references/config-plugin.md +90 -0
  58. package/plugins/lisa-expo/skills/expo-module/references/create-expo-module.md +206 -0
  59. package/plugins/lisa-expo/skills/expo-module/references/lifecycle.md +127 -0
  60. package/plugins/lisa-expo/skills/expo-module/references/module-config.md +48 -0
  61. package/plugins/lisa-expo/skills/expo-module/references/native-module.md +286 -0
  62. package/plugins/lisa-expo/skills/expo-module/references/native-view.md +171 -0
  63. package/plugins/lisa-expo/skills/expo-tailwind-setup/SKILL.md +480 -0
  64. package/plugins/lisa-expo/skills/expo-tailwind-setup/agents/openai.yaml +4 -0
  65. package/plugins/lisa-expo/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
  66. package/plugins/lisa-expo/skills/expo-ui-jetpack-compose/agents/openai.yaml +4 -0
  67. package/plugins/lisa-expo/skills/expo-ui-swift-ui/SKILL.md +39 -0
  68. package/plugins/lisa-expo/skills/expo-ui-swift-ui/agents/openai.yaml +4 -0
  69. package/plugins/lisa-expo/skills/native-data-fetching/SKILL.md +507 -0
  70. package/plugins/lisa-expo/skills/native-data-fetching/agents/openai.yaml +4 -0
  71. package/plugins/lisa-expo/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
  72. package/plugins/lisa-expo/skills/upgrading-expo/SKILL.md +134 -0
  73. package/plugins/lisa-expo/skills/upgrading-expo/agents/openai.yaml +4 -0
  74. package/plugins/lisa-expo/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
  75. package/plugins/lisa-expo/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
  76. package/plugins/lisa-expo/skills/upgrading-expo/references/native-tabs.md +124 -0
  77. package/plugins/lisa-expo/skills/upgrading-expo/references/new-architecture.md +79 -0
  78. package/plugins/lisa-expo/skills/upgrading-expo/references/react-19.md +79 -0
  79. package/plugins/lisa-expo/skills/upgrading-expo/references/react-compiler.md +59 -0
  80. package/plugins/lisa-expo/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
  81. package/plugins/lisa-expo/skills/use-dom/SKILL.md +417 -0
  82. package/plugins/lisa-expo/skills/use-dom/agents/openai.yaml +4 -0
  83. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  87. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  89. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  91. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  93. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  95. package/plugins/src/expo/.mcp.json +3 -3
  96. package/plugins/src/expo/THIRD-PARTY-NOTICES.md +57 -0
  97. package/plugins/src/expo/skills/add-app-clip/SKILL.md +280 -0
  98. package/plugins/src/expo/skills/add-app-clip/references/native-module.md +96 -0
  99. package/plugins/src/expo/skills/building-native-ui/SKILL.md +321 -0
  100. package/plugins/src/expo/skills/building-native-ui/references/animations.md +220 -0
  101. package/plugins/src/expo/skills/building-native-ui/references/controls.md +272 -0
  102. package/plugins/src/expo/skills/building-native-ui/references/form-sheet.md +253 -0
  103. package/plugins/src/expo/skills/building-native-ui/references/gradients.md +106 -0
  104. package/plugins/src/expo/skills/building-native-ui/references/icons.md +213 -0
  105. package/plugins/src/expo/skills/building-native-ui/references/media.md +198 -0
  106. package/plugins/src/expo/skills/building-native-ui/references/route-structure.md +229 -0
  107. package/plugins/src/expo/skills/building-native-ui/references/search.md +248 -0
  108. package/plugins/src/expo/skills/building-native-ui/references/storage.md +121 -0
  109. package/plugins/src/expo/skills/building-native-ui/references/tabs.md +433 -0
  110. package/plugins/src/expo/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
  111. package/plugins/src/expo/skills/building-native-ui/references/visual-effects.md +197 -0
  112. package/plugins/src/expo/skills/building-native-ui/references/webgpu-three.md +605 -0
  113. package/plugins/src/expo/skills/building-native-ui/references/zoom-transitions.md +158 -0
  114. package/plugins/src/expo/skills/eas-update-insights/SKILL.md +228 -0
  115. package/plugins/src/expo/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
  116. package/plugins/src/expo/skills/eas-update-insights/references/update-insights-schema.md +69 -0
  117. package/plugins/src/expo/skills/expo-api-routes/SKILL.md +369 -0
  118. package/plugins/src/expo/skills/expo-brownfield/SKILL.md +54 -0
  119. package/plugins/src/expo/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
  120. package/plugins/src/expo/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
  121. package/plugins/src/expo/skills/expo-brownfield/references/comparison.md +63 -0
  122. package/plugins/src/expo/skills/expo-brownfield/references/troubleshooting.md +88 -0
  123. package/plugins/src/expo/skills/expo-cicd-workflows/SKILL.md +92 -0
  124. package/plugins/src/expo/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
  125. package/plugins/src/expo/skills/expo-cicd-workflows/scripts/package.json +11 -0
  126. package/plugins/src/expo/skills/expo-cicd-workflows/scripts/validate.js +85 -0
  127. package/plugins/src/expo/skills/expo-deployment/SKILL.md +190 -0
  128. package/plugins/src/expo/skills/expo-deployment/references/app-store-metadata.md +479 -0
  129. package/plugins/src/expo/skills/expo-deployment/references/ios-app-store.md +355 -0
  130. package/plugins/src/expo/skills/expo-deployment/references/play-store.md +246 -0
  131. package/plugins/src/expo/skills/expo-deployment/references/testflight.md +58 -0
  132. package/plugins/src/expo/skills/expo-deployment/references/workflows.md +200 -0
  133. package/plugins/src/expo/skills/expo-dev-client/SKILL.md +164 -0
  134. package/plugins/src/expo/skills/expo-module/SKILL.md +141 -0
  135. package/plugins/src/expo/skills/expo-module/references/config-plugin.md +90 -0
  136. package/plugins/src/expo/skills/expo-module/references/create-expo-module.md +206 -0
  137. package/plugins/src/expo/skills/expo-module/references/lifecycle.md +127 -0
  138. package/plugins/src/expo/skills/expo-module/references/module-config.md +48 -0
  139. package/plugins/src/expo/skills/expo-module/references/native-module.md +286 -0
  140. package/plugins/src/expo/skills/expo-module/references/native-view.md +171 -0
  141. package/plugins/src/expo/skills/expo-tailwind-setup/SKILL.md +480 -0
  142. package/plugins/src/expo/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
  143. package/plugins/src/expo/skills/expo-ui-swift-ui/SKILL.md +39 -0
  144. package/plugins/src/expo/skills/native-data-fetching/SKILL.md +507 -0
  145. package/plugins/src/expo/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
  146. package/plugins/src/expo/skills/upgrading-expo/SKILL.md +134 -0
  147. package/plugins/src/expo/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
  148. package/plugins/src/expo/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
  149. package/plugins/src/expo/skills/upgrading-expo/references/native-tabs.md +124 -0
  150. package/plugins/src/expo/skills/upgrading-expo/references/new-architecture.md +79 -0
  151. package/plugins/src/expo/skills/upgrading-expo/references/react-19.md +79 -0
  152. package/plugins/src/expo/skills/upgrading-expo/references/react-compiler.md +59 -0
  153. package/plugins/src/expo/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
  154. package/plugins/src/expo/skills/use-dom/SKILL.md +417 -0
  155. package/scripts/generate-codex-plugin-artifacts.mjs +7 -2
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createHash } from "node:crypto";
4
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
5
+ import { resolve } from "node:path";
6
+ import process from "node:process";
7
+
8
+ const CACHE_DIRECTORY = resolve(import.meta.dirname, ".cache");
9
+ const DEFAULT_TTL_SECONDS = 15 * 60; // 15 minutes
10
+
11
+ export async function fetchCached(url) {
12
+ await mkdir(CACHE_DIRECTORY, { recursive: true });
13
+
14
+ const cacheFile = resolve(CACHE_DIRECTORY, hashUrl(url) + ".json");
15
+ const cached = await loadCacheEntry(cacheFile);
16
+ if (cached && cached.expires > Math.floor(Date.now() / 1000)) {
17
+ return cached.data;
18
+ }
19
+
20
+ // Make request, with conditional If-None-Match if we have an ETag.
21
+ // Cache-Control: max-age=0 overrides Node's default 'no-cache' to allow 304 responses.
22
+ const controller = new AbortController();
23
+ const timeout = setTimeout(() => controller.abort(), 15000);
24
+ const response = await fetch(url, {
25
+ headers: {
26
+ "Cache-Control": "max-age=0",
27
+ ...(cached?.etag && { "If-None-Match": cached.etag }),
28
+ },
29
+ signal: controller.signal,
30
+ });
31
+ clearTimeout(timeout);
32
+
33
+ if (response.status === 304 && cached) {
34
+ // Refresh expiration and return cached data
35
+ const entry = { ...cached, expires: getExpires(response.headers) };
36
+ await saveCacheEntry(cacheFile, entry);
37
+ return cached.data;
38
+ }
39
+
40
+ if (!response.ok) {
41
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
42
+ }
43
+
44
+ const etag = response.headers.get("etag");
45
+ const data = await response.text();
46
+ const expires = getExpires(response.headers);
47
+
48
+ await saveCacheEntry(cacheFile, { url, etag, expires, data });
49
+
50
+ return data;
51
+ }
52
+
53
+ function hashUrl(url) {
54
+ return createHash("sha256").update(url).digest("hex").slice(0, 16);
55
+ }
56
+
57
+ async function loadCacheEntry(cacheFile) {
58
+ try {
59
+ return JSON.parse(await readFile(cacheFile, "utf-8"));
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ async function saveCacheEntry(cacheFile, entry) {
66
+ await writeFile(cacheFile, JSON.stringify(entry, null, 2));
67
+ }
68
+
69
+ function getExpires(headers) {
70
+ const now = Math.floor(Date.now() / 1000);
71
+
72
+ // Prefer Cache-Control: max-age
73
+ const maxAgeSeconds = parseMaxAge(headers.get("cache-control"));
74
+ if (maxAgeSeconds != null) {
75
+ return now + maxAgeSeconds;
76
+ }
77
+
78
+ // Fall back to Expires header
79
+ const expires = headers.get("expires");
80
+ if (expires) {
81
+ const expiresTime = Date.parse(expires);
82
+ if (!Number.isNaN(expiresTime)) {
83
+ return Math.floor(expiresTime / 1000);
84
+ }
85
+ }
86
+
87
+ // Default TTL
88
+ return now + DEFAULT_TTL_SECONDS;
89
+ }
90
+
91
+ function parseMaxAge(cacheControl) {
92
+ if (!cacheControl) {
93
+ return null;
94
+ }
95
+ const match = cacheControl.match(/max-age=(\d+)/i);
96
+ return match ? parseInt(match[1], 10) : null;
97
+ }
98
+
99
+ if (import.meta.main) {
100
+ const url = process.argv[2];
101
+
102
+ if (!url || url === "--help" || url === "-h") {
103
+ console.log(`Usage: fetch <url>
104
+
105
+ Fetches a URL with HTTP caching (ETags + Cache-Control/Expires).
106
+ Default TTL: ${DEFAULT_TTL_SECONDS / 60} minutes.
107
+ Cache is stored in: ${CACHE_DIRECTORY}/`);
108
+ process.exit(url ? 0 : 1);
109
+ }
110
+
111
+ const data = await fetchCached(url);
112
+ console.log(data);
113
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@expo/cicd-workflows-skill",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "dependencies": {
7
+ "ajv": "^8.17.1",
8
+ "ajv-formats": "^3.0.1",
9
+ "js-yaml": "^4.1.0"
10
+ }
11
+ }
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFile } from "node:fs/promises";
4
+ import { resolve } from "node:path";
5
+ import process from "node:process";
6
+
7
+ import Ajv2020 from "ajv/dist/2020.js";
8
+ import addFormats from "ajv-formats";
9
+ import yaml from "js-yaml";
10
+
11
+ import { fetchCached } from "./fetch.js";
12
+
13
+ const SCHEMA_URL = "https://api.expo.dev/v2/workflows/schema";
14
+
15
+ async function fetchSchema() {
16
+ const data = await fetchCached(SCHEMA_URL);
17
+ const body = JSON.parse(data);
18
+ return body.data;
19
+ }
20
+
21
+ function createValidator(schema) {
22
+ const ajv = new Ajv2020({ allErrors: true, strict: true });
23
+ addFormats(ajv);
24
+ return ajv.compile(schema);
25
+ }
26
+
27
+ async function validateFile(validator, filePath) {
28
+ const content = await readFile(filePath, "utf-8");
29
+
30
+ let doc;
31
+ try {
32
+ doc = yaml.load(content);
33
+ } catch (e) {
34
+ return { valid: false, error: `YAML parse error: ${e.message}` };
35
+ }
36
+
37
+ const valid = validator(doc);
38
+ if (!valid) {
39
+ return { valid: false, error: formatErrors(validator.errors) };
40
+ }
41
+
42
+ return { valid: true };
43
+ }
44
+
45
+ function formatErrors(errors) {
46
+ return errors
47
+ .map(error => {
48
+ const path = error.instancePath || "(root)";
49
+ const allowed = error.params?.allowedValues?.join(", ");
50
+ return ` ${path}: ${error.message}${allowed ? ` (allowed: ${allowed})` : ""}`;
51
+ })
52
+ .join("\n");
53
+ }
54
+
55
+ if (import.meta.main) {
56
+ const args = process.argv.slice(2);
57
+ const files = args.filter(a => !a.startsWith("-"));
58
+
59
+ const wantsHelp = args.includes("--help") || args.includes("-h");
60
+ if (files.length === 0 || wantsHelp) {
61
+ console.log(`Usage: validate <workflow.yml> [workflow2.yml ...]
62
+
63
+ Validates EAS workflow YAML files against the official schema.`);
64
+ process.exit(wantsHelp ? 0 : 1);
65
+ }
66
+
67
+ const schema = await fetchSchema();
68
+ const validator = createValidator(schema);
69
+
70
+ let hasErrors = false;
71
+
72
+ for (const file of files) {
73
+ const filePath = resolve(process.cwd(), file);
74
+ const result = await validateFile(validator, filePath);
75
+
76
+ if (result.valid) {
77
+ console.log(`✓ ${file}`);
78
+ } else {
79
+ console.error(`✗ ${file}\n${result.error}`);
80
+ hasErrors = true;
81
+ }
82
+ }
83
+
84
+ process.exit(hasErrors ? 1 : 0);
85
+ }
@@ -0,0 +1,190 @@
1
+ ---
2
+ name: expo-deployment
3
+ description: Deploying Expo apps to iOS App Store, Android Play Store, web hosting, and API routes
4
+ version: 1.0.0
5
+ license: MIT
6
+ ---
7
+
8
+ # Deployment
9
+
10
+ This skill covers deploying Expo applications across all platforms using EAS (Expo Application Services).
11
+
12
+ ## References
13
+
14
+ Consult these resources as needed:
15
+
16
+ - ./references/workflows.md -- CI/CD workflows for automated deployments and PR previews
17
+ - ./references/testflight.md -- Submitting iOS builds to TestFlight for beta testing
18
+ - ./references/app-store-metadata.md -- Managing App Store metadata and ASO optimization
19
+ - ./references/play-store.md -- Submitting Android builds to Google Play Store
20
+ - ./references/ios-app-store.md -- iOS App Store submission and review process
21
+
22
+ ## Quick Start
23
+
24
+ ### Install EAS CLI
25
+
26
+ ```bash
27
+ npm install -g eas-cli
28
+ eas login
29
+ ```
30
+
31
+ ### Initialize EAS
32
+
33
+ ```bash
34
+ npx eas-cli@latest init
35
+ ```
36
+
37
+ This creates `eas.json` with build profiles.
38
+
39
+ ## Build Commands
40
+
41
+ ### Production Builds
42
+
43
+ ```bash
44
+ # iOS App Store build
45
+ npx eas-cli@latest build -p ios --profile production
46
+
47
+ # Android Play Store build
48
+ npx eas-cli@latest build -p android --profile production
49
+
50
+ # Both platforms
51
+ npx eas-cli@latest build --profile production
52
+ ```
53
+
54
+ ### Submit to Stores
55
+
56
+ ```bash
57
+ # iOS: Build and submit to App Store Connect
58
+ npx eas-cli@latest build -p ios --profile production --submit
59
+
60
+ # Android: Build and submit to Play Store
61
+ npx eas-cli@latest build -p android --profile production --submit
62
+
63
+ # Shortcut for iOS TestFlight
64
+ npx testflight
65
+ ```
66
+
67
+ ## Web Deployment
68
+
69
+ Deploy web apps using EAS Hosting:
70
+
71
+ ```bash
72
+ # Deploy to production
73
+ npx expo export -p web
74
+ npx eas-cli@latest deploy --prod
75
+
76
+ # Deploy PR preview
77
+ npx eas-cli@latest deploy
78
+ ```
79
+
80
+ ## EAS Configuration
81
+
82
+ Standard `eas.json` for production deployments:
83
+
84
+ ```json
85
+ {
86
+ "cli": {
87
+ "version": ">= 16.0.1",
88
+ "appVersionSource": "remote"
89
+ },
90
+ "build": {
91
+ "production": {
92
+ "autoIncrement": true,
93
+ "ios": {
94
+ "resourceClass": "m-medium"
95
+ }
96
+ },
97
+ "development": {
98
+ "developmentClient": true,
99
+ "distribution": "internal"
100
+ }
101
+ },
102
+ "submit": {
103
+ "production": {
104
+ "ios": {
105
+ "appleId": "your@email.com",
106
+ "ascAppId": "1234567890"
107
+ },
108
+ "android": {
109
+ "serviceAccountKeyPath": "./google-service-account.json",
110
+ "track": "internal"
111
+ }
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ ## Platform-Specific Guides
118
+
119
+ ### iOS
120
+
121
+ - Use `npx testflight` for quick TestFlight submissions
122
+ - Configure Apple credentials via `eas credentials`
123
+ - See ./references/testflight.md for credential setup
124
+ - See ./references/ios-app-store.md for App Store submission
125
+
126
+ ### Android
127
+
128
+ - Set up Google Play Console service account
129
+ - Configure tracks: internal → closed → open → production
130
+ - See ./references/play-store.md for detailed setup
131
+
132
+ ### Web
133
+
134
+ - EAS Hosting provides preview URLs for PRs
135
+ - Production deploys to your custom domain
136
+ - See ./references/workflows.md for CI/CD automation
137
+
138
+ ## Automated Deployments
139
+
140
+ Use EAS Workflows for CI/CD:
141
+
142
+ ```yaml
143
+ # .eas/workflows/release.yml
144
+ name: Release
145
+
146
+ on:
147
+ push:
148
+ branches: [main]
149
+
150
+ jobs:
151
+ build-ios:
152
+ type: build
153
+ params:
154
+ platform: ios
155
+ profile: production
156
+
157
+ submit-ios:
158
+ type: submit
159
+ needs: [build-ios]
160
+ params:
161
+ platform: ios
162
+ profile: production
163
+ ```
164
+
165
+ See ./references/workflows.md for more workflow examples.
166
+
167
+ ## Version Management
168
+
169
+ EAS manages version numbers automatically with `appVersionSource: "remote"`:
170
+
171
+ ```bash
172
+ # Check current versions
173
+ eas build:version:get
174
+
175
+ # Manually set version
176
+ eas build:version:set -p ios --build-number 42
177
+ ```
178
+
179
+ ## Monitoring
180
+
181
+ ```bash
182
+ # List recent builds
183
+ eas build:list
184
+
185
+ # Check build status
186
+ eas build:view
187
+
188
+ # View submission status
189
+ eas submit:list
190
+ ```