@jetstart/cli 1.6.0 → 2.0.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 (142) hide show
  1. package/README.md +133 -41
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +11 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/android-emulator.d.ts.map +1 -0
  6. package/dist/commands/android-emulator.js.map +1 -0
  7. package/dist/commands/build.d.ts +13 -1
  8. package/dist/commands/build.d.ts.map +1 -0
  9. package/dist/commands/build.js +279 -29
  10. package/dist/commands/build.js.map +1 -0
  11. package/dist/commands/clean.d.ts +23 -0
  12. package/dist/commands/clean.d.ts.map +1 -0
  13. package/dist/commands/clean.js +191 -0
  14. package/dist/commands/clean.js.map +1 -0
  15. package/dist/commands/create.d.ts.map +1 -0
  16. package/dist/commands/create.js +41 -0
  17. package/dist/commands/create.js.map +1 -0
  18. package/dist/commands/dev.d.ts.map +1 -0
  19. package/dist/commands/dev.js +51 -9
  20. package/dist/commands/dev.js.map +1 -0
  21. package/dist/commands/index.d.ts.map +1 -0
  22. package/dist/commands/index.js.map +1 -0
  23. package/dist/commands/install-audit.d.ts.map +1 -0
  24. package/dist/commands/install-audit.js.map +1 -0
  25. package/dist/commands/logs.d.ts.map +1 -0
  26. package/dist/commands/logs.js.map +1 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/types/index.d.ts.map +1 -0
  30. package/dist/types/index.js.map +1 -0
  31. package/dist/utils/android-sdk.d.ts.map +1 -0
  32. package/dist/utils/android-sdk.js +2 -2
  33. package/dist/utils/android-sdk.js.map +1 -0
  34. package/dist/utils/downloader.d.ts.map +1 -0
  35. package/dist/utils/downloader.js.map +1 -0
  36. package/dist/utils/emulator-deployer.d.ts.map +1 -0
  37. package/dist/utils/emulator-deployer.js.map +1 -0
  38. package/dist/utils/emulator.d.ts.map +1 -0
  39. package/dist/utils/emulator.js +5 -4
  40. package/dist/utils/emulator.js.map +1 -0
  41. package/dist/utils/index.d.ts.map +1 -0
  42. package/dist/utils/index.js.map +1 -0
  43. package/dist/utils/java.d.ts.map +1 -0
  44. package/dist/utils/java.js +5 -5
  45. package/dist/utils/java.js.map +1 -0
  46. package/dist/utils/logger.d.ts.map +1 -0
  47. package/dist/utils/logger.js.map +1 -0
  48. package/dist/utils/open.d.ts.map +1 -0
  49. package/dist/utils/open.js.map +1 -0
  50. package/dist/utils/prompt.d.ts.map +1 -0
  51. package/dist/utils/prompt.js.map +1 -0
  52. package/dist/utils/spinner.d.ts.map +1 -0
  53. package/dist/utils/spinner.js.map +1 -0
  54. package/dist/utils/system-tools.d.ts.map +1 -0
  55. package/dist/utils/system-tools.js.map +1 -0
  56. package/dist/utils/template.d.ts +13 -1
  57. package/dist/utils/template.d.ts.map +1 -0
  58. package/dist/utils/template.js +133 -1003
  59. package/dist/utils/template.js.map +1 -0
  60. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/1.0.0/com.jetstart.hot-reload.gradle.plugin-1.0.0.pom +15 -0
  61. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/1.0.0/com.jetstart.hot-reload.gradle.plugin-1.0.0.pom.md5 +1 -0
  62. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/1.0.0/com.jetstart.hot-reload.gradle.plugin-1.0.0.pom.sha1 +1 -0
  63. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/1.0.0/com.jetstart.hot-reload.gradle.plugin-1.0.0.pom.sha256 +1 -0
  64. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/1.0.0/com.jetstart.hot-reload.gradle.plugin-1.0.0.pom.sha512 +1 -0
  65. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/maven-metadata.xml +13 -0
  66. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/maven-metadata.xml.md5 +1 -0
  67. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/maven-metadata.xml.sha1 +1 -0
  68. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/maven-metadata.xml.sha256 +1 -0
  69. package/maven-repo/com/jetstart/hot-reload/com.jetstart.hot-reload.gradle.plugin/maven-metadata.xml.sha512 +1 -0
  70. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0-sources.jar +0 -0
  71. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0-sources.jar.md5 +1 -0
  72. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0-sources.jar.sha1 +1 -0
  73. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0-sources.jar.sha256 +1 -0
  74. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0-sources.jar.sha512 +1 -0
  75. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.aar +0 -0
  76. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.aar.md5 +1 -0
  77. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.aar.sha1 +1 -0
  78. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.aar.sha256 +1 -0
  79. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.aar.sha512 +1 -0
  80. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.module +124 -0
  81. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.module.md5 +1 -0
  82. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.module.sha1 +1 -0
  83. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.module.sha256 +1 -0
  84. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.module.sha512 +1 -0
  85. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.pom +46 -0
  86. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.pom.md5 +1 -0
  87. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.pom.sha1 +1 -0
  88. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.pom.sha256 +1 -0
  89. package/maven-repo/com/jetstart/hot-reload-runtime/1.0.0/hot-reload-runtime-1.0.0.pom.sha512 +1 -0
  90. package/maven-repo/com/jetstart/hot-reload-runtime/maven-metadata.xml +13 -0
  91. package/maven-repo/com/jetstart/hot-reload-runtime/maven-metadata.xml.md5 +1 -0
  92. package/maven-repo/com/jetstart/hot-reload-runtime/maven-metadata.xml.sha1 +1 -0
  93. package/maven-repo/com/jetstart/hot-reload-runtime/maven-metadata.xml.sha256 +1 -0
  94. package/maven-repo/com/jetstart/hot-reload-runtime/maven-metadata.xml.sha512 +1 -0
  95. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.jar +0 -0
  96. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.jar.md5 +1 -0
  97. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.jar.sha1 +1 -0
  98. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.jar.sha256 +1 -0
  99. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.jar.sha512 +1 -0
  100. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.module +103 -0
  101. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.module.md5 +1 -0
  102. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.module.sha1 +1 -0
  103. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.module.sha256 +1 -0
  104. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.module.sha512 +1 -0
  105. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.pom +38 -0
  106. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.pom.md5 +1 -0
  107. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.pom.sha1 +1 -0
  108. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.pom.sha256 +1 -0
  109. package/maven-repo/com/jetstart/jetstart-gradle-plugin/1.0.0/jetstart-gradle-plugin-1.0.0.pom.sha512 +1 -0
  110. package/maven-repo/com/jetstart/jetstart-gradle-plugin/maven-metadata.xml +13 -0
  111. package/maven-repo/com/jetstart/jetstart-gradle-plugin/maven-metadata.xml.md5 +1 -0
  112. package/maven-repo/com/jetstart/jetstart-gradle-plugin/maven-metadata.xml.sha1 +1 -0
  113. package/maven-repo/com/jetstart/jetstart-gradle-plugin/maven-metadata.xml.sha256 +1 -0
  114. package/maven-repo/com/jetstart/jetstart-gradle-plugin/maven-metadata.xml.sha512 +1 -0
  115. package/package.json +13 -5
  116. package/scripts/build-java.js +30 -0
  117. package/.eslintrc.json +0 -6
  118. package/src/cli.ts +0 -99
  119. package/src/commands/android-emulator.ts +0 -304
  120. package/src/commands/build.ts +0 -60
  121. package/src/commands/create.ts +0 -232
  122. package/src/commands/dev.ts +0 -198
  123. package/src/commands/index.ts +0 -10
  124. package/src/commands/install-audit.ts +0 -227
  125. package/src/commands/logs.ts +0 -117
  126. package/src/index.ts +0 -17
  127. package/src/types/index.ts +0 -53
  128. package/src/utils/android-sdk.ts +0 -512
  129. package/src/utils/downloader.ts +0 -201
  130. package/src/utils/emulator-deployer.ts +0 -210
  131. package/src/utils/emulator.ts +0 -463
  132. package/src/utils/index.ts +0 -8
  133. package/src/utils/java.ts +0 -369
  134. package/src/utils/logger.ts +0 -42
  135. package/src/utils/open.ts +0 -36
  136. package/src/utils/prompt.ts +0 -56
  137. package/src/utils/spinner.ts +0 -25
  138. package/src/utils/system-tools.ts +0 -648
  139. package/src/utils/template.ts +0 -1217
  140. package/tests/create.test.ts +0 -33
  141. package/tests/utils.test.ts +0 -17
  142. package/tsconfig.json +0 -25
package/.eslintrc.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "extends": "../../.eslintrc.json",
3
- "parserOptions": {
4
- "project": ["./tsconfig.json", "./tsconfig.tests.json"]
5
- }
6
- }
package/src/cli.ts DELETED
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * CLI Entry Point
5
- * Defines all commands and handles command execution
6
- */
7
-
8
- import { Command } from 'commander';
9
- import chalk from 'chalk';
10
- import { createCommand } from './commands/create';
11
- import { devCommand } from './commands/dev';
12
- import { buildCommand } from './commands/build';
13
- import { logsCommand } from './commands/logs';
14
- import { installAuditCommand } from './commands/install-audit';
15
- import { androidEmulatorCommand } from './commands/android-emulator';
16
- import { JETSTART_VERSION } from '@jetstart/shared';
17
- import {version} from '../package.json';
18
- const program = new Command();
19
-
20
- program
21
- .name('jetstart')
22
- .description('Fast, wireless Android development with Kotlin and Jetpack Compose')
23
- .version(version || JETSTART_VERSION);
24
-
25
- // Create command
26
- program
27
- .command('create <name>')
28
- .description('Create a new JetStart project')
29
- .option('-p, --package <name>', 'Package name (e.g., com.example.app)')
30
- .option('-t, --template <name>', 'Template to use', 'default')
31
- .option('--skip-install', 'Skip npm install')
32
- .option('--full-install', 'Automatically install all required Android dependencies')
33
- .action(createCommand);
34
-
35
- // Dev command
36
- program
37
- .command('dev')
38
- .description('Start development server')
39
- .option('-p, --port <port>', 'Port for dev server', '8765')
40
- .option('-H, --host <host>', 'Host address (defaults to auto-detected network IP)')
41
- .option('--no-qr', 'Do not show QR code')
42
- .option('--no-open', 'Do not open browser')
43
- .option('--web', 'Open Web Emulator automatically')
44
- .option('--emulator', 'Deploy to running Android emulator')
45
- .option('--avd <name>', 'Target specific emulator by name')
46
- .action(devCommand);
47
-
48
- // Build command
49
- program
50
- .command('build')
51
- .description('Build production APK')
52
- .option('-o, --output <path>', 'Output directory', './build')
53
- .option('-r, --release', 'Build release version', false)
54
- .option('--sign', 'Sign the APK')
55
- .action(buildCommand);
56
-
57
- // Logs command
58
- program
59
- .command('logs')
60
- .description('Stream application logs')
61
- .option('-f, --follow', 'Follow log output', true)
62
- .option('-l, --level <level>', 'Filter by log level')
63
- .option('-s, --source <source>', 'Filter by log source')
64
- .option('-n, --lines <number>', 'Number of lines to show', '100')
65
- .action(logsCommand);
66
-
67
- // Install audit command
68
- program
69
- .command('install-audit')
70
- .description('Audit installation of required tools and dependencies')
71
- .option('--json', 'Output results in JSON format')
72
- .action(installAuditCommand);
73
-
74
- // Android emulator command
75
- program
76
- .command('android-emulator')
77
- .description('Manage Android emulators (AVDs)')
78
- .action(androidEmulatorCommand);
79
-
80
- // Error handling
81
- program.on('command:*', (operands) => {
82
- console.error(chalk.red(`Error: Unknown command '${operands[0]}'`));
83
- console.log(chalk.yellow('\nRun "jetstart --help" for available commands'));
84
- process.exit(1);
85
- });
86
-
87
- // Handle errors gracefully
88
- process.on('unhandledRejection', (err: Error) => {
89
- console.error(chalk.red('Unhandled error:'), err.message);
90
- process.exit(1);
91
- });
92
-
93
- // Parse arguments
94
- program.parse(process.argv);
95
-
96
- // Show help if no command provided
97
- if (!process.argv.slice(2).length) {
98
- program.outputHelp();
99
- }
@@ -1,304 +0,0 @@
1
- /**
2
- * Android emulator management command
3
- */
4
-
5
- import inquirer from 'inquirer';
6
- import chalk from 'chalk';
7
- import { createAVDManager } from '../utils/emulator';
8
- import { error as logError, success, info, warning } from '../utils/logger';
9
-
10
- /**
11
- * Display list of AVDs
12
- */
13
- async function handleListAVDs(): Promise<void> {
14
- const avdManager = createAVDManager();
15
-
16
- const avds = await avdManager.listAVDs();
17
-
18
- if (avds.length === 0) {
19
- console.log();
20
- warning('No Android emulators found.');
21
- console.log();
22
-
23
- const { shouldCreate } = await inquirer.prompt([
24
- {
25
- type: 'confirm',
26
- name: 'shouldCreate',
27
- message: 'Would you like to create a JetStart-optimized emulator?',
28
- default: true,
29
- },
30
- ]);
31
-
32
- if (shouldCreate) {
33
- await handleCreateJetStartAVD();
34
- }
35
- return;
36
- }
37
-
38
- console.log();
39
- console.log(chalk.bold('Available Android Virtual Devices:'));
40
- console.log('━'.repeat(70));
41
- console.log();
42
-
43
- for (const avd of avds) {
44
- const statusIcon = avd.running ? chalk.green('✓') : chalk.gray('○');
45
- const statusText = avd.running ? chalk.green('(Running)') : '';
46
-
47
- console.log(` ${statusIcon} ${chalk.bold(avd.name)} ${statusText}`);
48
- console.log(` - Device: ${avd.device || 'Unknown'}`);
49
- console.log(` - Target: ${avd.target || 'Unknown'}`);
50
- if (avd.basedOn) {
51
- console.log(` - Based on: ${avd.basedOn}`);
52
- }
53
- console.log();
54
- }
55
- }
56
-
57
- /**
58
- * Start an emulator
59
- */
60
- async function handleStartEmulator(): Promise<void> {
61
- const avdManager = createAVDManager();
62
- const avds = await avdManager.listAVDs();
63
-
64
- if (avds.length === 0) {
65
- warning('No emulators available. Create one first.');
66
- return;
67
- }
68
-
69
- // Filter out running emulators
70
- const availableAVDs = avds.filter((avd) => !avd.running);
71
-
72
- if (availableAVDs.length === 0) {
73
- info('All emulators are already running.');
74
- return;
75
- }
76
-
77
- const { avdName } = await inquirer.prompt([
78
- {
79
- type: 'list',
80
- name: 'avdName',
81
- message: 'Select emulator to start:',
82
- choices: availableAVDs.map((avd) => ({ name: `${avd.name} (${avd.target})`, value: avd.name })),
83
- },
84
- ]);
85
-
86
- await avdManager.startEmulator({ avdName });
87
- }
88
-
89
- /**
90
- * Stop an emulator
91
- */
92
- async function handleStopEmulator(): Promise<void> {
93
- const avdManager = createAVDManager();
94
- const avds = await avdManager.listAVDs();
95
-
96
- // Filter running emulators
97
- const runningAVDs = avds.filter((avd) => avd.running);
98
-
99
- if (runningAVDs.length === 0) {
100
- warning('No emulators are currently running.');
101
- return;
102
- }
103
-
104
- const { avdName } = await inquirer.prompt([
105
- {
106
- type: 'list',
107
- name: 'avdName',
108
- message: 'Select emulator to stop:',
109
- choices: runningAVDs.map((avd) => ({ name: `${avd.name} (${avd.target})`, value: avd.name })),
110
- },
111
- ]);
112
-
113
- await avdManager.stopEmulator(avdName);
114
- }
115
-
116
- /**
117
- * Create JetStart-optimized AVD
118
- */
119
- async function handleCreateJetStartAVD(): Promise<void> {
120
- const avdManager = createAVDManager();
121
-
122
- try {
123
- await avdManager.createJetStartAVD();
124
- } catch (err: any) {
125
- logError(`Failed to create AVD: ${err.message}`);
126
- }
127
- }
128
-
129
- /**
130
- * Create custom AVD
131
- */
132
- async function handleCreateCustomAVD(): Promise<void> {
133
- const avdManager = createAVDManager();
134
-
135
- const answers = await inquirer.prompt([
136
- {
137
- type: 'input',
138
- name: 'name',
139
- message: 'Enter AVD name:',
140
- default: 'my-android-emulator',
141
- validate: (input: string) => {
142
- if (!input || input.trim().length === 0) {
143
- return 'Name cannot be empty';
144
- }
145
- if (!/^[a-zA-Z0-9_-]+$/.test(input)) {
146
- return 'Name can only contain letters, numbers, hyphens, and underscores';
147
- }
148
- return true;
149
- },
150
- },
151
- {
152
- type: 'list',
153
- name: 'device',
154
- message: 'Select device profile:',
155
- choices: [
156
- { name: 'Pixel 5', value: 'pixel_5' },
157
- { name: 'Pixel 6', value: 'pixel_6' },
158
- { name: 'Pixel 8', value: 'pixel_8' },
159
- { name: 'Nexus 5', value: 'Nexus 5' },
160
- ],
161
- default: 'pixel_5',
162
- },
163
- {
164
- type: 'list',
165
- name: 'apiLevel',
166
- message: 'Select API level:',
167
- choices: [
168
- { name: 'API 34 (Android 14) - Recommended', value: 34 },
169
- { name: 'API 33 (Android 13)', value: 33 },
170
- { name: 'API 31 (Android 12)', value: 31 },
171
- { name: 'API 29 (Android 10)', value: 29 },
172
- { name: 'API 24 (Android 7.0) - Minimum', value: 24 },
173
- ],
174
- default: 34,
175
- },
176
- {
177
- type: 'list',
178
- name: 'abi',
179
- message: 'Select ABI (architecture):',
180
- choices: [
181
- { name: 'x86_64 (Intel/AMD 64-bit)', value: 'x86_64' },
182
- { name: 'arm64-v8a (ARM 64-bit)', value: 'arm64-v8a' },
183
- ],
184
- default: process.arch === 'arm64' ? 'arm64-v8a' : 'x86_64',
185
- },
186
- ]);
187
-
188
- try {
189
- await avdManager.createAVD({
190
- name: answers.name,
191
- device: answers.device,
192
- apiLevel: answers.apiLevel,
193
- abi: answers.abi,
194
- });
195
- } catch (err: any) {
196
- logError(`Failed to create AVD: ${err.message}`);
197
- }
198
- }
199
-
200
- /**
201
- * Delete an AVD
202
- */
203
- async function handleDeleteAVD(): Promise<void> {
204
- const avdManager = createAVDManager();
205
- const avds = await avdManager.listAVDs();
206
-
207
- if (avds.length === 0) {
208
- warning('No emulators available to delete.');
209
- return;
210
- }
211
-
212
- const { avdName } = await inquirer.prompt([
213
- {
214
- type: 'list',
215
- name: 'avdName',
216
- message: 'Select emulator to delete:',
217
- choices: avds.map((avd) => ({ name: `${avd.name} (${avd.target})`, value: avd.name })),
218
- },
219
- ]);
220
-
221
- const { confirm } = await inquirer.prompt([
222
- {
223
- type: 'confirm',
224
- name: 'confirm',
225
- message: `Are you sure you want to delete "${avdName}"?`,
226
- default: false,
227
- },
228
- ]);
229
-
230
- if (confirm) {
231
- await avdManager.deleteAVD(avdName);
232
- } else {
233
- info('Deletion cancelled');
234
- }
235
- }
236
-
237
- /**
238
- * Android emulator command handler
239
- */
240
- export async function androidEmulatorCommand(): Promise<void> {
241
- try {
242
- console.log();
243
- console.log(chalk.cyan.bold(' JetStart Android Emulator Manager'));
244
- console.log();
245
-
246
- let running = true;
247
-
248
- while (running) {
249
- const { action } = await inquirer.prompt([
250
- {
251
- type: 'list',
252
- name: 'action',
253
- message: 'What would you like to do?',
254
- choices: [
255
- { name: 'List existing emulators', value: 'list' },
256
- { name: 'Start emulator', value: 'start' },
257
- { name: 'Stop emulator', value: 'stop' },
258
- new inquirer.Separator(),
259
- { name: 'Create JetStart-optimized emulator', value: 'create-jetstart' },
260
- { name: 'Create custom emulator', value: 'create-custom' },
261
- { name: 'Delete emulator', value: 'delete' },
262
- new inquirer.Separator(),
263
- { name: 'Exit', value: 'exit' },
264
- ],
265
- },
266
- ]);
267
-
268
- switch (action) {
269
- case 'list':
270
- await handleListAVDs();
271
- break;
272
- case 'start':
273
- await handleStartEmulator();
274
- break;
275
- case 'stop':
276
- await handleStopEmulator();
277
- break;
278
- case 'create-jetstart':
279
- await handleCreateJetStartAVD();
280
- break;
281
- case 'create-custom':
282
- await handleCreateCustomAVD();
283
- break;
284
- case 'delete':
285
- await handleDeleteAVD();
286
- break;
287
- case 'exit':
288
- running = false;
289
- console.log();
290
- success('Goodbye!');
291
- console.log();
292
- break;
293
- }
294
-
295
- if (running && action !== 'list') {
296
- console.log();
297
- }
298
- }
299
- } catch (err: any) {
300
- console.log();
301
- logError(`Emulator management failed: ${err.message}`);
302
- process.exit(1);
303
- }
304
- }
@@ -1,60 +0,0 @@
1
- /**
2
- * Build Command
3
- * Builds production APK
4
- */
5
-
6
- import path from 'path';
7
- import chalk from 'chalk';
8
- import { log, success, error, info } from '../utils/logger';
9
- import { startSpinner, stopSpinner } from '../utils/spinner';
10
- import { BuildType } from '@jetstart/shared';
11
-
12
- interface BuildOptions {
13
- output?: string;
14
- release?: boolean;
15
- sign?: boolean;
16
- }
17
-
18
- export async function buildCommand(options: BuildOptions) {
19
- try {
20
- const buildType = options.release ? BuildType.RELEASE : BuildType.DEBUG;
21
- const outputDir = options.output || './build';
22
-
23
- log(`Building ${buildType} APK...`);
24
- console.log();
25
-
26
- // Validate project
27
- const spinner = startSpinner('Validating project...');
28
- await new Promise(resolve => setTimeout(resolve, 500));
29
- stopSpinner(spinner, true, 'Project validated');
30
-
31
- // Compile Kotlin
32
- const compileSpinner = startSpinner('Compiling Kotlin sources...');
33
- await new Promise(resolve => setTimeout(resolve, 2000));
34
- stopSpinner(compileSpinner, true, 'Kotlin compiled');
35
-
36
- // Package APK
37
- const packageSpinner = startSpinner('Packaging APK...');
38
- await new Promise(resolve => setTimeout(resolve, 1500));
39
- stopSpinner(packageSpinner, true, 'APK packaged');
40
-
41
- // Sign APK (if release)
42
- if (options.release && options.sign) {
43
- const signSpinner = startSpinner('Signing APK...');
44
- await new Promise(resolve => setTimeout(resolve, 800));
45
- stopSpinner(signSpinner, true, 'APK signed');
46
- }
47
-
48
- console.log();
49
- success('Build completed successfully!');
50
- console.log();
51
- info(`Output: ${chalk.cyan(path.resolve(outputDir))}`);
52
- info(`Size: ${chalk.cyan('5.2 MB')}`);
53
- info(`Type: ${chalk.cyan(buildType)}`);
54
- console.log();
55
-
56
- } catch (err: any) {
57
- error(`Build failed: ${err.message}`);
58
- process.exit(1);
59
- }
60
- }
@@ -1,232 +0,0 @@
1
- /**
2
- * Create Command
3
- * Scaffolds a new JetStart project
4
- */
5
-
6
- import path from 'path';
7
- import fs from 'fs-extra';
8
- import chalk from 'chalk';
9
- import inquirer from 'inquirer';
10
- import { log, success, error, info, warning } from '../utils/logger';
11
- import { startSpinner, stopSpinner } from '../utils/spinner';
12
- import { prompt } from '../utils/prompt';
13
- import { generateProjectTemplate } from '../utils/template';
14
- import { isValidProjectName, isValidPackageName } from '@jetstart/shared';
15
- import { CreateOptions } from '../types';
16
- import { detectJava, installJava, isJavaCompatible } from '../utils/java';
17
- import { createSDKManager, REQUIRED_SDK_COMPONENTS } from '../utils/android-sdk';
18
- import { findAndroidSDK } from '../utils/system-tools';
19
-
20
- /**
21
- * Run full installation (automated mode)
22
- */
23
- async function runFullInstallation(): Promise<void> {
24
- info('Starting full automated installation...');
25
- console.log();
26
-
27
- // 1. Check and install Java
28
- const java = await detectJava();
29
- if (!java || !(await isJavaCompatible(java.version))) {
30
- await installJava();
31
- } else {
32
- success(`Java ${java.version} already installed`);
33
- }
34
-
35
- // 2. Check and install Android SDK
36
- const sdkManager = createSDKManager();
37
- const sdkRoot = await findAndroidSDK();
38
-
39
- if (!sdkRoot) {
40
- info('Installing Android SDK components...');
41
- await sdkManager.installCmdlineTools();
42
- } else {
43
- success(`Android SDK found at ${sdkRoot}`);
44
- }
45
-
46
- // 3. Install required SDK components
47
- for (const component of REQUIRED_SDK_COMPONENTS) {
48
- await sdkManager.installComponent(component);
49
- }
50
-
51
- console.log();
52
- success('All dependencies installed successfully!');
53
- console.log();
54
- }
55
-
56
- /**
57
- * Run interactive installation
58
- */
59
- async function runInteractiveInstallation(): Promise<void> {
60
- info('Checking dependencies...');
61
- console.log();
62
-
63
- // Check Java
64
- const java = await detectJava();
65
- if (!java || !(await isJavaCompatible(java.version))) {
66
- const { shouldInstall } = await inquirer.prompt([
67
- {
68
- type: 'confirm',
69
- name: 'shouldInstall',
70
- message: 'Java 17+ not found. Would you like to install it?',
71
- default: true,
72
- },
73
- ]);
74
-
75
- if (shouldInstall) {
76
- await installJava();
77
- } else {
78
- warning('Java installation skipped. You may need to install it manually.');
79
- }
80
- } else {
81
- success(`Java ${java.version} detected`);
82
- }
83
-
84
- // Check Android SDK
85
- const sdkRoot = await findAndroidSDK();
86
- if (!sdkRoot) {
87
- const { shouldInstall } = await inquirer.prompt([
88
- {
89
- type: 'confirm',
90
- name: 'shouldInstall',
91
- message: 'Android SDK not found. Would you like to install it?',
92
- default: true,
93
- },
94
- ]);
95
-
96
- if (shouldInstall) {
97
- const sdkManager = createSDKManager();
98
- await sdkManager.installCmdlineTools();
99
-
100
- // Ask about components
101
- const { installComponents } = await inquirer.prompt([
102
- {
103
- type: 'confirm',
104
- name: 'installComponents',
105
- message: 'Install required SDK components?',
106
- default: true,
107
- },
108
- ]);
109
-
110
- if (installComponents) {
111
- for (const component of REQUIRED_SDK_COMPONENTS) {
112
- await sdkManager.installComponent(component);
113
- }
114
- }
115
- } else {
116
- warning('Android SDK installation skipped. Project creation may fail without SDK.');
117
- }
118
- } else {
119
- success(`Android SDK found at ${sdkRoot}`);
120
- }
121
-
122
- console.log();
123
- }
124
-
125
- export async function createCommand(name: string, options: CreateOptions) {
126
- try {
127
- // Validate project name
128
- if (!isValidProjectName(name)) {
129
- error('Invalid project name. Use letters, numbers, hyphens, and underscores only.');
130
- error('Project name must start with a letter and be 1-64 characters long.');
131
- process.exit(1);
132
- }
133
-
134
- const projectPath = path.resolve(process.cwd(), name);
135
-
136
- // Check if directory already exists
137
- if (await fs.pathExists(projectPath)) {
138
- error(`Directory '${name}' already exists!`);
139
- process.exit(1);
140
- }
141
-
142
- log(`Creating JetStart project: ${chalk.cyan(name)}`);
143
- console.log();
144
-
145
- // Run installation if requested
146
- if (options.fullInstall) {
147
- await runFullInstallation();
148
- } else {
149
- // Interactive mode: ask user
150
- const { shouldCheckDeps } = await inquirer.prompt([
151
- {
152
- type: 'confirm',
153
- name: 'shouldCheckDeps',
154
- message: 'Check and install dependencies?',
155
- default: true,
156
- },
157
- ]);
158
-
159
- if (shouldCheckDeps) {
160
- await runInteractiveInstallation();
161
- }
162
- }
163
-
164
- // Get package name
165
- let packageName = options.package;
166
- if (!packageName) {
167
- const defaultPackage = `com.jetstart.${name.toLowerCase().replace(/[^a-z0-9]/g, '')}`;
168
- const answer = await prompt({
169
- type: 'input',
170
- name: 'packageName',
171
- message: 'Package name:',
172
- default: defaultPackage,
173
- validate: (input: string) => {
174
- if (!isValidPackageName(input)) {
175
- return 'Invalid package name. Use format: com.company.app';
176
- }
177
- return true;
178
- },
179
- });
180
- packageName = answer.packageName;
181
- }
182
-
183
- // Validate package name
184
- if (!isValidPackageName(packageName!)) {
185
- error('Invalid package name. Use format: com.company.app');
186
- process.exit(1);
187
- }
188
-
189
- // Create project structure
190
- const spinner = startSpinner('Creating project structure...');
191
-
192
- try {
193
- await fs.ensureDir(projectPath);
194
-
195
- // Generate project files
196
- await generateProjectTemplate(projectPath, {
197
- projectName: name,
198
- packageName: packageName!,
199
- template: options.template || 'default',
200
- });
201
-
202
- stopSpinner(spinner, true, 'Project structure created');
203
-
204
- // Install dependencies
205
- if (!options.skipInstall) {
206
- const installSpinner = startSpinner('Installing dependencies...');
207
-
208
- // In a real implementation, we'd run npm/gradle here
209
- // For now, we'll simulate it
210
- await new Promise(resolve => setTimeout(resolve, 1000));
211
-
212
- stopSpinner(installSpinner, true, 'Dependencies installed');
213
- }
214
-
215
- console.log();
216
- success(`Successfully created project: ${chalk.cyan(name)}`);
217
- console.log();
218
- console.log(chalk.bold('Next steps:'));
219
- console.log(` ${chalk.cyan('cd')} ${name}`);
220
- console.log(` ${chalk.cyan('jetstart dev')}`);
221
- console.log();
222
-
223
- } catch (err: any) {
224
- stopSpinner(spinner, false, 'Failed to create project');
225
- throw err;
226
- }
227
-
228
- } catch (err: any) {
229
- error(`Failed to create project: ${err.message}`);
230
- process.exit(1);
231
- }
232
- }