acadex-cli 1.1.0 → 1.2.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/README.md CHANGED
@@ -53,25 +53,24 @@ npm link
53
53
 
54
54
  ## Usage
55
55
 
56
- Run the CLI tool using:
56
+ ### Interactive Menu (New in v1.1!)
57
+
58
+ Launch the interactive menu with arrow key navigation:
57
59
 
58
60
  ```bash
59
- acadex <command> [arguments]
61
+ acadex menu
60
62
  ```
61
63
 
62
- ### Interactive Menu (New!)
64
+ Navigate through categories using arrow keys and select commands easily!
63
65
 
64
- For a modern, interactive experience:
66
+ ### Command Line
67
+
68
+ Run the CLI tool using:
65
69
 
66
70
  ```bash
67
- acadex menu
71
+ acadex <command> [arguments]
68
72
  ```
69
73
 
70
- This will launch an interactive menu where you can:
71
- - Browse all available commands by category
72
- - Select commands by number
73
- - Execute commands without memorizing syntax
74
-
75
74
  ### Available Commands
76
75
 
77
76
  #### Setup & Installation
package/acadex CHANGED
@@ -70,11 +70,11 @@ show_help() {
70
70
  echo -e " ${GREEN}phpmyadmin:stop${NC} Stop Apache"
71
71
  echo -e " ${GREEN}docs${NC} Open ACADEX documentation"
72
72
  echo -e " ${GREEN}uninstall${NC} Uninstall ACADEX CLI globally"
73
- echo -e " ${GREEN}menu${NC} Launch interactive menu"
73
+ echo -e " ${GREEN}menu${NC} Interactive menu (modern UI)"
74
74
  echo ""
75
75
  echo -e "${YELLOW}Examples:${NC}"
76
+ echo -e " acadex menu # Launch interactive menu"
76
77
  echo -e " acadex setup # First-time installation"
77
- echo -e " acadex menu # Interactive command menu"
78
78
  echo -e " acadex services # Start services for Herd (recommended)"
79
79
  echo -e " acadex serve # Start full stack (without Herd)"
80
80
  echo -e " acadex dev # Start development"
@@ -83,84 +83,271 @@ show_help() {
83
83
  echo ""
84
84
  }
85
85
 
86
- # Interactive Menu
86
+ # Interactive menu
87
87
  show_menu() {
88
88
  while true; do
89
89
  clear
90
90
  echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
91
- echo -e "${BLUE}║${NC} ${GREEN}ACADEX${NC} - Interactive Command Menu ${BLUE}║${NC}"
91
+ echo -e "${BLUE}║${NC} ${GREEN}ACADEX${NC} - Interactive Menu ${YELLOW}(Select Category)${NC} ${BLUE}║${NC}"
92
92
  echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
93
93
  echo ""
94
- echo -e "${YELLOW}Setup & Installation:${NC}"
95
- echo -e " ${GREEN}1)${NC} setup - First-time full installation"
96
- echo -e " ${GREEN}2)${NC} install:2fa - Install 2FA packages"
97
- echo -e " ${GREEN}3)${NC} install:notif - Install notification packages"
98
- echo -e " ${GREEN}4)${NC} check - Check system requirements"
99
- echo ""
100
- echo -e "${YELLOW}Development:${NC}"
101
- echo -e " ${GREEN}5)${NC} serve - Start production servers"
102
- echo -e " ${GREEN}6)${NC} services - Start background services (Herd)"
103
- echo -e " ${GREEN}7)${NC} dev - Start development servers"
104
- echo -e " ${GREEN}8)${NC} build - Build assets for production"
105
- echo -e " ${GREEN}9)${NC} ui - Rebuild UI and clear caches"
106
- echo -e " ${GREEN}10)${NC} start - Start Laravel server only"
107
- echo ""
108
- echo -e "${YELLOW}Testing:${NC}"
109
- echo -e " ${GREEN}11)${NC} test - Run PHPUnit tests"
110
- echo -e " ${GREEN}12)${NC} test:coverage - Run tests with coverage"
111
- echo ""
112
- echo -e "${YELLOW}Database:${NC}"
113
- echo -e " ${GREEN}13)${NC} migrate - Run database migrations"
114
- echo -e " ${GREEN}14)${NC} migrate:fresh - Fresh migration with seeders"
115
- echo -e " ${GREEN}15)${NC} seed - Run database seeders"
116
- echo -e " ${GREEN}16)${NC} tinker - Start Laravel Tinker"
117
- echo ""
118
- echo -e "${YELLOW}Maintenance:${NC}"
119
- echo -e " ${GREEN}17)${NC} cache:clear - Clear all caches"
120
- echo -e " ${GREEN}18)${NC} optimize - Optimize the application"
121
- echo -e " ${GREEN}19)${NC} logs - Tail Laravel logs"
122
- echo ""
123
- echo -e "${YELLOW}Code Quality:${NC}"
124
- echo -e " ${GREEN}20)${NC} analyze - Run PHPStan static analysis"
125
- echo -e " ${GREEN}21)${NC} format - Format code with Pint"
126
- echo ""
127
- echo -e "${YELLOW}Other:${NC}"
128
- echo -e " ${GREEN}22)${NC} routes - List all routes"
129
- echo -e " ${GREEN}23)${NC} queue - Start queue worker"
130
- echo -e " ${GREEN}24)${NC} docs - Open ACADEX documentation"
131
- echo ""
132
- echo -e " ${RED}0)${NC} Exit"
133
- echo ""
134
- echo -e -n "${YELLOW}Select an option [0-24]:${NC} "
135
- read choice
94
+ echo -e "${YELLOW}Main Menu:${NC}"
95
+ echo ""
96
+ echo -e " ${GREEN}1)${NC} 📦 Setup & Installation"
97
+ echo -e " ${GREEN}2)${NC} 🚀 Development"
98
+ echo -e " ${GREEN}3)${NC} 🧪 Testing"
99
+ echo -e " ${GREEN}4)${NC} 💾 Database"
100
+ echo -e " ${GREEN}5)${NC} 🔧 Maintenance"
101
+ echo -e " ${GREEN}6)${NC} 📊 Code Quality"
102
+ echo -e " ${GREEN}7)${NC} 📦 Dependencies"
103
+ echo -e " ${GREEN}8)${NC} 🛠️ Other Tools"
104
+ echo ""
105
+ echo -e " ${RED}0)${NC} Exit"
106
+ echo ""
107
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
108
+ read -p "$(echo -e ${YELLOW}Select category [0-8]:${NC} )" category
109
+
110
+ case $category in
111
+ 1) show_setup_menu ;;
112
+ 2) show_development_menu ;;
113
+ 3) show_testing_menu ;;
114
+ 4) show_database_menu ;;
115
+ 5) show_maintenance_menu ;;
116
+ 6) show_code_quality_menu ;;
117
+ 7) show_dependencies_menu ;;
118
+ 8) show_other_menu ;;
119
+ 0) echo -e "\n${GREEN}Goodbye!${NC}"; exit 0 ;;
120
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
121
+ esac
122
+ done
123
+ }
124
+
125
+ # Setup & Installation submenu
126
+ show_setup_menu() {
127
+ while true; do
128
+ clear
129
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
130
+ echo -e "${BLUE}║${NC} ${GREEN}📦 Setup & Installation${NC} ${BLUE}║${NC}"
131
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
132
+ echo ""
133
+ echo -e " ${GREEN}1)${NC} setup - First-time full installation"
134
+ echo -e " ${GREEN}2)${NC} install:2fa - Install 2FA packages"
135
+ echo -e " ${GREEN}3)${NC} install:notif - Install notification packages"
136
+ echo -e " ${GREEN}4)${NC} check - Check system requirements"
137
+ echo ""
138
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
139
+ echo ""
140
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
141
+ read -p "$(echo -e ${YELLOW}Select option [0-4]:${NC} )" choice
142
+
143
+ case $choice in
144
+ 1) echo ""; "$0" setup; read -p "Press Enter to continue..." ;;
145
+ 2) echo ""; "$0" install:2fa; read -p "Press Enter to continue..." ;;
146
+ 3) echo ""; "$0" install:notif; read -p "Press Enter to continue..." ;;
147
+ 4) echo ""; "$0" check; read -p "Press Enter to continue..." ;;
148
+ 0) return ;;
149
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
150
+ esac
151
+ done
152
+ }
153
+
154
+ # Development submenu
155
+ show_development_menu() {
156
+ while true; do
157
+ clear
158
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
159
+ echo -e "${BLUE}║${NC} ${GREEN}🚀 Development${NC} ${BLUE}║${NC}"
160
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
161
+ echo ""
162
+ echo -e " ${GREEN}1)${NC} serve - Start production servers (Laravel + Queue + Scheduler + Reverb)"
163
+ echo -e " ${GREEN}2)${NC} services - Start background services only (for Herd)"
164
+ echo -e " ${GREEN}3)${NC} dev - Start dev servers (Laravel + Queue + Logs + Vite + Reverb)"
165
+ echo -e " ${GREEN}4)${NC} build - Build assets for production"
166
+ echo -e " ${GREEN}5)${NC} ui - Rebuild UI assets and clear caches"
167
+ echo -e " ${GREEN}6)${NC} start - Start Laravel server only"
168
+ echo ""
169
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
170
+ echo ""
171
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
172
+ read -p "$(echo -e ${YELLOW}Select option [0-6]:${NC} )" choice
173
+
174
+ case $choice in
175
+ 1) echo ""; "$0" serve ;;
176
+ 2) echo ""; "$0" services ;;
177
+ 3) echo ""; "$0" dev ;;
178
+ 4) echo ""; "$0" build; read -p "Press Enter to continue..." ;;
179
+ 5) echo ""; "$0" ui; read -p "Press Enter to continue..." ;;
180
+ 6) echo ""; "$0" start ;;
181
+ 0) return ;;
182
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
183
+ esac
184
+ done
185
+ }
186
+
187
+ # Testing submenu
188
+ show_testing_menu() {
189
+ while true; do
190
+ clear
191
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
192
+ echo -e "${BLUE}║${NC} ${GREEN}🧪 Testing${NC} ${BLUE}║${NC}"
193
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
194
+ echo ""
195
+ echo -e " ${GREEN}1)${NC} test - Run PHPUnit tests"
196
+ echo -e " ${GREEN}2)${NC} test:coverage - Run tests with coverage"
197
+ echo ""
198
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
199
+ echo ""
200
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
201
+ read -p "$(echo -e ${YELLOW}Select option [0-2]:${NC} )" choice
202
+
203
+ case $choice in
204
+ 1) echo ""; "$0" test; read -p "Press Enter to continue..." ;;
205
+ 2) echo ""; "$0" test:coverage; read -p "Press Enter to continue..." ;;
206
+ 0) return ;;
207
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
208
+ esac
209
+ done
210
+ }
211
+
212
+ # Database submenu
213
+ show_database_menu() {
214
+ while true; do
215
+ clear
216
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
217
+ echo -e "${BLUE}║${NC} ${GREEN}💾 Database${NC} ${BLUE}║${NC}"
218
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
219
+ echo ""
220
+ echo -e " ${GREEN}1)${NC} migrate - Run database migrations"
221
+ echo -e " ${GREEN}2)${NC} migrate:fresh - Fresh migration with seeders"
222
+ echo -e " ${GREEN}3)${NC} seed - Run database seeders"
223
+ echo -e " ${GREEN}4)${NC} tinker - Start Laravel Tinker"
224
+ echo ""
225
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
226
+ echo ""
227
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
228
+ read -p "$(echo -e ${YELLOW}Select option [0-4]:${NC} )" choice
229
+
230
+ case $choice in
231
+ 1) echo ""; "$0" migrate; read -p "Press Enter to continue..." ;;
232
+ 2) echo ""; "$0" migrate:fresh; read -p "Press Enter to continue..." ;;
233
+ 3) echo ""; "$0" seed; read -p "Press Enter to continue..." ;;
234
+ 4) echo ""; "$0" tinker ;;
235
+ 0) return ;;
236
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
237
+ esac
238
+ done
239
+ }
240
+
241
+ # Maintenance submenu
242
+ show_maintenance_menu() {
243
+ while true; do
244
+ clear
245
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
246
+ echo -e "${BLUE}║${NC} ${GREEN}🔧 Maintenance${NC} ${BLUE}║${NC}"
247
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
248
+ echo ""
249
+ echo -e " ${GREEN}1)${NC} cache:clear - Clear all caches"
250
+ echo -e " ${GREEN}2)${NC} optimize - Optimize the application"
251
+ echo -e " ${GREEN}3)${NC} logs - Tail Laravel logs"
252
+ echo ""
253
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
254
+ echo ""
255
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
256
+ read -p "$(echo -e ${YELLOW}Select option [0-3]:${NC} )" choice
257
+
258
+ case $choice in
259
+ 1) echo ""; "$0" cache:clear; read -p "Press Enter to continue..." ;;
260
+ 2) echo ""; "$0" optimize; read -p "Press Enter to continue..." ;;
261
+ 3) echo ""; "$0" logs ;;
262
+ 0) return ;;
263
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
264
+ esac
265
+ done
266
+ }
267
+
268
+ # Code Quality submenu
269
+ show_code_quality_menu() {
270
+ while true; do
271
+ clear
272
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
273
+ echo -e "${BLUE}║${NC} ${GREEN}📊 Code Quality${NC} ${BLUE}║${NC}"
274
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
275
+ echo ""
276
+ echo -e " ${GREEN}1)${NC} analyze - Run PHPStan static analysis"
277
+ echo -e " ${GREEN}2)${NC} format - Format code with Pint"
278
+ echo ""
279
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
280
+ echo ""
281
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
282
+ read -p "$(echo -e ${YELLOW}Select option [0-2]:${NC} )" choice
283
+
284
+ case $choice in
285
+ 1) echo ""; "$0" analyze; read -p "Press Enter to continue..." ;;
286
+ 2) echo ""; "$0" format; read -p "Press Enter to continue..." ;;
287
+ 0) return ;;
288
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
289
+ esac
290
+ done
291
+ }
292
+
293
+ # Dependencies submenu
294
+ show_dependencies_menu() {
295
+ while true; do
296
+ clear
297
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
298
+ echo -e "${BLUE}║${NC} ${GREEN}📦 Dependencies${NC} ${BLUE}║${NC}"
299
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
300
+ echo ""
301
+ echo -e " ${GREEN}1)${NC} install - Install all dependencies"
302
+ echo -e " ${GREEN}2)${NC} update - Update all dependencies"
303
+ echo ""
304
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
305
+ echo ""
306
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
307
+ read -p "$(echo -e ${YELLOW}Select option [0-2]:${NC} )" choice
308
+
309
+ case $choice in
310
+ 1) echo ""; "$0" install; read -p "Press Enter to continue..." ;;
311
+ 2) echo ""; "$0" update; read -p "Press Enter to continue..." ;;
312
+ 0) return ;;
313
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
314
+ esac
315
+ done
316
+ }
317
+
318
+ # Other Tools submenu
319
+ show_other_menu() {
320
+ while true; do
321
+ clear
322
+ echo -e "${BLUE}╔══════════════════════════════════════════════════════════╗${NC}"
323
+ echo -e "${BLUE}║${NC} ${GREEN}🛠️ Other Tools${NC} ${BLUE}║${NC}"
324
+ echo -e "${BLUE}╚══════════════════════════════════════════════════════════╝${NC}"
325
+ echo ""
326
+ echo -e " ${GREEN}1)${NC} routes - List all routes"
327
+ echo -e " ${GREEN}2)${NC} queue - Start queue worker"
328
+ echo -e " ${GREEN}3)${NC} schedule - Run scheduled tasks"
329
+ echo -e " ${GREEN}4)${NC} share - Share site publicly via Expose"
330
+ echo -e " ${GREEN}5)${NC} phpmyadmin - Start Apache & open phpMyAdmin"
331
+ echo -e " ${GREEN}6)${NC} phpmyadmin:stop - Stop Apache"
332
+ echo -e " ${GREEN}7)${NC} docs - Open ACADEX documentation"
333
+ echo -e " ${GREEN}8)${NC} uninstall - Uninstall ACADEX CLI globally"
334
+ echo ""
335
+ echo -e " ${YELLOW}0)${NC} ← Back to Main Menu"
336
+ echo ""
337
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
338
+ read -p "$(echo -e ${YELLOW}Select option [0-8]:${NC} )" choice
136
339
 
137
340
  case $choice in
138
- 1) "$0" setup ;;
139
- 2) "$0" install:2fa ;;
140
- 3) "$0" install:notif ;;
141
- 4) "$0" check; read -p "Press Enter to continue..." ;;
142
- 5) "$0" serve ;;
143
- 6) "$0" services ;;
144
- 7) "$0" dev ;;
145
- 8) "$0" build; read -p "Press Enter to continue..." ;;
146
- 9) "$0" ui; read -p "Press Enter to continue..." ;;
147
- 10) "$0" start ;;
148
- 11) "$0" test; read -p "Press Enter to continue..." ;;
149
- 12) "$0" test:coverage; read -p "Press Enter to continue..." ;;
150
- 13) "$0" migrate; read -p "Press Enter to continue..." ;;
151
- 14) "$0" migrate:fresh; read -p "Press Enter to continue..." ;;
152
- 15) "$0" seed; read -p "Press Enter to continue..." ;;
153
- 16) "$0" tinker ;;
154
- 17) "$0" cache:clear; read -p "Press Enter to continue..." ;;
155
- 18) "$0" optimize; read -p "Press Enter to continue..." ;;
156
- 19) "$0" logs ;;
157
- 20) "$0" analyze; read -p "Press Enter to continue..." ;;
158
- 21) "$0" format; read -p "Press Enter to continue..." ;;
159
- 22) "$0" routes; read -p "Press Enter to continue..." ;;
160
- 23) "$0" queue ;;
161
- 24) "$0" docs; read -p "Press Enter to continue..." ;;
162
- 0) echo -e "${GREEN}Goodbye!${NC}"; exit 0 ;;
163
- *) echo -e "${RED}Invalid option. Please try again.${NC}"; sleep 2 ;;
341
+ 1) echo ""; "$0" routes; read -p "Press Enter to continue..." ;;
342
+ 2) echo ""; "$0" queue ;;
343
+ 3) echo ""; "$0" schedule; read -p "Press Enter to continue..." ;;
344
+ 4) echo ""; "$0" share ;;
345
+ 5) echo ""; "$0" phpmyadmin; read -p "Press Enter to continue..." ;;
346
+ 6) echo ""; "$0" phpmyadmin:stop; read -p "Press Enter to continue..." ;;
347
+ 7) echo ""; "$0" docs; read -p "Press Enter to continue..." ;;
348
+ 8) echo ""; "$0" uninstall ;;
349
+ 0) return ;;
350
+ *) echo -e "${RED}Invalid option!${NC}"; sleep 1 ;;
164
351
  esac
165
352
  done
166
353
  }
package/acadex.ps1 CHANGED
@@ -103,11 +103,11 @@ function Show-Help {
103
103
  Write-Host " uninstall " -ForegroundColor Green -NoNewline
104
104
  Write-Host "Uninstall ACADEX CLI globally"
105
105
  Write-Host " menu " -ForegroundColor Green -NoNewline
106
- Write-Host "Launch interactive menu"
106
+ Write-Host "Interactive menu (modern UI)"
107
107
  Write-Host ""
108
108
  Write-Host "Examples:" -ForegroundColor Yellow
109
+ Write-Host " acadex menu # Launch interactive menu"
109
110
  Write-Host " acadex setup # First-time installation"
110
- Write-Host " acadex menu # Interactive command menu"
111
111
  Write-Host " acadex services # Start services for Herd/Laragon (recommended)"
112
112
  Write-Host " acadex serve # Start full stack (without Herd/Laragon)"
113
113
  Write-Host " acadex dev # Start development"
@@ -116,91 +116,271 @@ function Show-Help {
116
116
  Write-Host ""
117
117
  }
118
118
 
119
- # Interactive Menu
119
+ # Check if a command exists
120
+ function Test-CommandExists {
121
+ param([string]$Cmd)
122
+ $null -ne (Get-Command $Cmd -ErrorAction SilentlyContinue)
123
+ }
124
+
125
+ # Interactive menu
120
126
  function Show-Menu {
121
127
  while ($true) {
122
128
  Clear-Host
123
129
  Write-Host "===========================================================" -ForegroundColor Cyan
124
- Write-Host " ACADEX - Interactive Command Menu " -ForegroundColor Green
130
+ Write-Host " ACADEX - Interactive Menu (Select Category) " -ForegroundColor Green
125
131
  Write-Host "===========================================================" -ForegroundColor Cyan
126
132
  Write-Host ""
127
- Write-Host "Setup & Installation:" -ForegroundColor Yellow
128
- Write-Host " 1) setup - First-time full installation" -ForegroundColor Green
129
- Write-Host " 2) install:2fa - Install 2FA packages" -ForegroundColor Green
130
- Write-Host " 3) install:notif - Install notification packages" -ForegroundColor Green
131
- Write-Host " 4) check - Check system requirements" -ForegroundColor Green
133
+ Write-Host "Main Menu:" -ForegroundColor Yellow
132
134
  Write-Host ""
133
- Write-Host "Development:" -ForegroundColor Yellow
134
- Write-Host " 5) serve - Start production servers" -ForegroundColor Green
135
- Write-Host " 6) services - Start background services (Herd)" -ForegroundColor Green
136
- Write-Host " 7) dev - Start development servers" -ForegroundColor Green
137
- Write-Host " 8) build - Build assets for production" -ForegroundColor Green
138
- Write-Host " 9) ui - Rebuild UI and clear caches" -ForegroundColor Green
139
- Write-Host " 10) start - Start Laravel server only" -ForegroundColor Green
135
+ Write-Host " 1) 📦 Setup & Installation" -ForegroundColor Green
136
+ Write-Host " 2) 🚀 Development" -ForegroundColor Green
137
+ Write-Host " 3) 🧪 Testing" -ForegroundColor Green
138
+ Write-Host " 4) 💾 Database" -ForegroundColor Green
139
+ Write-Host " 5) 🔧 Maintenance" -ForegroundColor Green
140
+ Write-Host " 6) 📊 Code Quality" -ForegroundColor Green
141
+ Write-Host " 7) 📦 Dependencies" -ForegroundColor Green
142
+ Write-Host " 8) 🛠️ Other Tools" -ForegroundColor Green
140
143
  Write-Host ""
141
- Write-Host "Testing:" -ForegroundColor Yellow
142
- Write-Host " 11) test - Run PHPUnit tests" -ForegroundColor Green
143
- Write-Host " 12) test:coverage - Run tests with coverage" -ForegroundColor Green
144
+ Write-Host " 0) ❌ Exit" -ForegroundColor Red
144
145
  Write-Host ""
145
- Write-Host "Database:" -ForegroundColor Yellow
146
- Write-Host " 13) migrate - Run database migrations" -ForegroundColor Green
147
- Write-Host " 14) migrate:fresh - Fresh migration with seeders" -ForegroundColor Green
148
- Write-Host " 15) seed - Run database seeders" -ForegroundColor Green
149
- Write-Host " 16) tinker - Start Laravel Tinker" -ForegroundColor Green
146
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
147
+ $category = Read-Host "Select category [0-8]"
148
+
149
+ switch ($category) {
150
+ "1" { Show-SetupMenu }
151
+ "2" { Show-DevelopmentMenu }
152
+ "3" { Show-TestingMenu }
153
+ "4" { Show-DatabaseMenu }
154
+ "5" { Show-MaintenanceMenu }
155
+ "6" { Show-CodeQualityMenu }
156
+ "7" { Show-DependenciesMenu }
157
+ "8" { Show-OtherMenu }
158
+ "0" { Write-Host ""; Write-Host "Goodbye!" -ForegroundColor Green; return }
159
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
160
+ }
161
+ }
162
+ }
163
+
164
+ function Show-SetupMenu {
165
+ while ($true) {
166
+ Clear-Host
167
+ Write-Host "===========================================================" -ForegroundColor Cyan
168
+ Write-Host " 📦 Setup & Installation " -ForegroundColor Green
169
+ Write-Host "===========================================================" -ForegroundColor Cyan
150
170
  Write-Host ""
151
- Write-Host "Maintenance:" -ForegroundColor Yellow
152
- Write-Host " 17) cache:clear - Clear all caches" -ForegroundColor Green
153
- Write-Host " 18) optimize - Optimize the application" -ForegroundColor Green
154
- Write-Host " 19) logs - Tail Laravel logs" -ForegroundColor Green
171
+ Write-Host " 1) setup - First-time full installation" -ForegroundColor Green
172
+ Write-Host " 2) install:2fa - Install 2FA packages" -ForegroundColor Green
173
+ Write-Host " 3) install:notif - Install notification packages" -ForegroundColor Green
174
+ Write-Host " 4) check - Check system requirements" -ForegroundColor Green
155
175
  Write-Host ""
156
- Write-Host "Code Quality:" -ForegroundColor Yellow
157
- Write-Host " 20) analyze - Run PHPStan static analysis" -ForegroundColor Green
158
- Write-Host " 21) format - Format code with Pint" -ForegroundColor Green
176
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
159
177
  Write-Host ""
160
- Write-Host "Other:" -ForegroundColor Yellow
161
- Write-Host " 22) routes - List all routes" -ForegroundColor Green
162
- Write-Host " 23) queue - Start queue worker" -ForegroundColor Green
163
- Write-Host " 24) docs - Open ACADEX documentation" -ForegroundColor Green
178
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
179
+ $choice = Read-Host "Select option [0-4]"
180
+
181
+ switch ($choice) {
182
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "setup"; Read-Host "Press Enter to continue" }
183
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "install:2fa"; Read-Host "Press Enter to continue" }
184
+ "3" { Write-Host ""; & $MyInvocation.MyCommand.Path "install:notif"; Read-Host "Press Enter to continue" }
185
+ "4" { Write-Host ""; & $MyInvocation.MyCommand.Path "check"; Read-Host "Press Enter to continue" }
186
+ "0" { return }
187
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
188
+ }
189
+ }
190
+ }
191
+
192
+ function Show-DevelopmentMenu {
193
+ while ($true) {
194
+ Clear-Host
195
+ Write-Host "===========================================================" -ForegroundColor Cyan
196
+ Write-Host " 🚀 Development " -ForegroundColor Green
197
+ Write-Host "===========================================================" -ForegroundColor Cyan
198
+ Write-Host ""
199
+ Write-Host " 1) serve - Start production servers" -ForegroundColor Green
200
+ Write-Host " 2) services - Start background services only (for Herd)" -ForegroundColor Green
201
+ Write-Host " 3) dev - Start dev servers" -ForegroundColor Green
202
+ Write-Host " 4) build - Build assets for production" -ForegroundColor Green
203
+ Write-Host " 5) ui - Rebuild UI assets and clear caches" -ForegroundColor Green
204
+ Write-Host " 6) start - Start Laravel server only" -ForegroundColor Green
164
205
  Write-Host ""
165
- Write-Host " 0) Exit" -ForegroundColor Red
206
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
166
207
  Write-Host ""
167
- $choice = Read-Host "Select an option [0-24]"
208
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
209
+ $choice = Read-Host "Select option [0-6]"
168
210
 
169
211
  switch ($choice) {
170
- "1" { & $MyInvocation.MyCommand.Path setup }
171
- "2" { & $MyInvocation.MyCommand.Path install:2fa }
172
- "3" { & $MyInvocation.MyCommand.Path install:notif }
173
- "4" { & $MyInvocation.MyCommand.Path check; Read-Host "Press Enter to continue" }
174
- "5" { & $MyInvocation.MyCommand.Path serve }
175
- "6" { & $MyInvocation.MyCommand.Path services }
176
- "7" { & $MyInvocation.MyCommand.Path dev }
177
- "8" { & $MyInvocation.MyCommand.Path build; Read-Host "Press Enter to continue" }
178
- "9" { & $MyInvocation.MyCommand.Path ui; Read-Host "Press Enter to continue" }
179
- "10" { & $MyInvocation.MyCommand.Path start }
180
- "11" { & $MyInvocation.MyCommand.Path test; Read-Host "Press Enter to continue" }
181
- "12" { & $MyInvocation.MyCommand.Path test:coverage; Read-Host "Press Enter to continue" }
182
- "13" { & $MyInvocation.MyCommand.Path migrate; Read-Host "Press Enter to continue" }
183
- "14" { & $MyInvocation.MyCommand.Path migrate:fresh; Read-Host "Press Enter to continue" }
184
- "15" { & $MyInvocation.MyCommand.Path seed; Read-Host "Press Enter to continue" }
185
- "16" { & $MyInvocation.MyCommand.Path tinker }
186
- "17" { & $MyInvocation.MyCommand.Path cache:clear; Read-Host "Press Enter to continue" }
187
- "18" { & $MyInvocation.MyCommand.Path optimize; Read-Host "Press Enter to continue" }
188
- "19" { & $MyInvocation.MyCommand.Path logs }
189
- "20" { & $MyInvocation.MyCommand.Path analyze; Read-Host "Press Enter to continue" }
190
- "21" { & $MyInvocation.MyCommand.Path format; Read-Host "Press Enter to continue" }
191
- "22" { & $MyInvocation.MyCommand.Path routes; Read-Host "Press Enter to continue" }
192
- "23" { & $MyInvocation.MyCommand.Path queue }
193
- "24" { & $MyInvocation.MyCommand.Path docs; Read-Host "Press Enter to continue" }
194
- "0" { Write-Host "Goodbye!" -ForegroundColor Green; exit 0 }
195
- default { Write-Host "Invalid option. Please try again." -ForegroundColor Red; Start-Sleep -Seconds 2 }
212
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "serve" }
213
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "services" }
214
+ "3" { Write-Host ""; & $MyInvocation.MyCommand.Path "dev" }
215
+ "4" { Write-Host ""; & $MyInvocation.MyCommand.Path "build"; Read-Host "Press Enter to continue" }
216
+ "5" { Write-Host ""; & $MyInvocation.MyCommand.Path "ui"; Read-Host "Press Enter to continue" }
217
+ "6" { Write-Host ""; & $MyInvocation.MyCommand.Path "start" }
218
+ "0" { return }
219
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
196
220
  }
197
221
  }
198
222
  }
199
223
 
200
- # Check if a command exists
201
- function Test-CommandExists {
202
- param([string]$Cmd)
203
- $null -ne (Get-Command $Cmd -ErrorAction SilentlyContinue)
224
+ function Show-TestingMenu {
225
+ while ($true) {
226
+ Clear-Host
227
+ Write-Host "===========================================================" -ForegroundColor Cyan
228
+ Write-Host " 🧪 Testing " -ForegroundColor Green
229
+ Write-Host "===========================================================" -ForegroundColor Cyan
230
+ Write-Host ""
231
+ Write-Host " 1) test - Run PHPUnit tests" -ForegroundColor Green
232
+ Write-Host " 2) test:coverage - Run tests with coverage" -ForegroundColor Green
233
+ Write-Host ""
234
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
235
+ Write-Host ""
236
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
237
+ $choice = Read-Host "Select option [0-2]"
238
+
239
+ switch ($choice) {
240
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "test"; Read-Host "Press Enter to continue" }
241
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "test:coverage"; Read-Host "Press Enter to continue" }
242
+ "0" { return }
243
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
244
+ }
245
+ }
246
+ }
247
+
248
+ function Show-DatabaseMenu {
249
+ while ($true) {
250
+ Clear-Host
251
+ Write-Host "===========================================================" -ForegroundColor Cyan
252
+ Write-Host " 💾 Database " -ForegroundColor Green
253
+ Write-Host "===========================================================" -ForegroundColor Cyan
254
+ Write-Host ""
255
+ Write-Host " 1) migrate - Run database migrations" -ForegroundColor Green
256
+ Write-Host " 2) migrate:fresh - Fresh migration with seeders" -ForegroundColor Green
257
+ Write-Host " 3) seed - Run database seeders" -ForegroundColor Green
258
+ Write-Host " 4) tinker - Start Laravel Tinker" -ForegroundColor Green
259
+ Write-Host ""
260
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
261
+ Write-Host ""
262
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
263
+ $choice = Read-Host "Select option [0-4]"
264
+
265
+ switch ($choice) {
266
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "migrate"; Read-Host "Press Enter to continue" }
267
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "migrate:fresh"; Read-Host "Press Enter to continue" }
268
+ "3" { Write-Host ""; & $MyInvocation.MyCommand.Path "seed"; Read-Host "Press Enter to continue" }
269
+ "4" { Write-Host ""; & $MyInvocation.MyCommand.Path "tinker" }
270
+ "0" { return }
271
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
272
+ }
273
+ }
274
+ }
275
+
276
+ function Show-MaintenanceMenu {
277
+ while ($true) {
278
+ Clear-Host
279
+ Write-Host "===========================================================" -ForegroundColor Cyan
280
+ Write-Host " 🔧 Maintenance " -ForegroundColor Green
281
+ Write-Host "===========================================================" -ForegroundColor Cyan
282
+ Write-Host ""
283
+ Write-Host " 1) cache:clear - Clear all caches" -ForegroundColor Green
284
+ Write-Host " 2) optimize - Optimize the application" -ForegroundColor Green
285
+ Write-Host " 3) logs - Tail Laravel logs" -ForegroundColor Green
286
+ Write-Host ""
287
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
288
+ Write-Host ""
289
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
290
+ $choice = Read-Host "Select option [0-3]"
291
+
292
+ switch ($choice) {
293
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "cache:clear"; Read-Host "Press Enter to continue" }
294
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "optimize"; Read-Host "Press Enter to continue" }
295
+ "3" { Write-Host ""; & $MyInvocation.MyCommand.Path "logs" }
296
+ "0" { return }
297
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
298
+ }
299
+ }
300
+ }
301
+
302
+ function Show-CodeQualityMenu {
303
+ while ($true) {
304
+ Clear-Host
305
+ Write-Host "===========================================================" -ForegroundColor Cyan
306
+ Write-Host " 📊 Code Quality " -ForegroundColor Green
307
+ Write-Host "===========================================================" -ForegroundColor Cyan
308
+ Write-Host ""
309
+ Write-Host " 1) analyze - Run PHPStan static analysis" -ForegroundColor Green
310
+ Write-Host " 2) format - Format code with Pint" -ForegroundColor Green
311
+ Write-Host ""
312
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
313
+ Write-Host ""
314
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
315
+ $choice = Read-Host "Select option [0-2]"
316
+
317
+ switch ($choice) {
318
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "analyze"; Read-Host "Press Enter to continue" }
319
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "format"; Read-Host "Press Enter to continue" }
320
+ "0" { return }
321
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
322
+ }
323
+ }
324
+ }
325
+
326
+ function Show-DependenciesMenu {
327
+ while ($true) {
328
+ Clear-Host
329
+ Write-Host "===========================================================" -ForegroundColor Cyan
330
+ Write-Host " 📦 Dependencies " -ForegroundColor Green
331
+ Write-Host "===========================================================" -ForegroundColor Cyan
332
+ Write-Host ""
333
+ Write-Host " 1) install - Install all dependencies" -ForegroundColor Green
334
+ Write-Host " 2) update - Update all dependencies" -ForegroundColor Green
335
+ Write-Host ""
336
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
337
+ Write-Host ""
338
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
339
+ $choice = Read-Host "Select option [0-2]"
340
+
341
+ switch ($choice) {
342
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "install"; Read-Host "Press Enter to continue" }
343
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "update"; Read-Host "Press Enter to continue" }
344
+ "0" { return }
345
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
346
+ }
347
+ }
348
+ }
349
+
350
+ function Show-OtherMenu {
351
+ while ($true) {
352
+ Clear-Host
353
+ Write-Host "===========================================================" -ForegroundColor Cyan
354
+ Write-Host " 🛠️ Other Tools " -ForegroundColor Green
355
+ Write-Host "===========================================================" -ForegroundColor Cyan
356
+ Write-Host ""
357
+ Write-Host " 1) routes - List all routes" -ForegroundColor Green
358
+ Write-Host " 2) queue - Start queue worker" -ForegroundColor Green
359
+ Write-Host " 3) schedule - Run scheduled tasks" -ForegroundColor Green
360
+ Write-Host " 4) share - Share site publicly via Expose" -ForegroundColor Green
361
+ Write-Host " 5) phpmyadmin - Start Apache & open phpMyAdmin" -ForegroundColor Green
362
+ Write-Host " 6) phpmyadmin:stop - Stop Apache" -ForegroundColor Green
363
+ Write-Host " 7) docs - Open ACADEX documentation" -ForegroundColor Green
364
+ Write-Host " 8) uninstall - Uninstall ACADEX CLI globally" -ForegroundColor Green
365
+ Write-Host ""
366
+ Write-Host " 0) ← Back to Main Menu" -ForegroundColor Yellow
367
+ Write-Host ""
368
+ Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
369
+ $choice = Read-Host "Select option [0-8]"
370
+
371
+ switch ($choice) {
372
+ "1" { Write-Host ""; & $MyInvocation.MyCommand.Path "routes"; Read-Host "Press Enter to continue" }
373
+ "2" { Write-Host ""; & $MyInvocation.MyCommand.Path "queue" }
374
+ "3" { Write-Host ""; & $MyInvocation.MyCommand.Path "schedule"; Read-Host "Press Enter to continue" }
375
+ "4" { Write-Host ""; & $MyInvocation.MyCommand.Path "share" }
376
+ "5" { Write-Host ""; & $MyInvocation.MyCommand.Path "phpmyadmin"; Read-Host "Press Enter to continue" }
377
+ "6" { Write-Host ""; & $MyInvocation.MyCommand.Path "phpmyadmin:stop"; Read-Host "Press Enter to continue" }
378
+ "7" { Write-Host ""; & $MyInvocation.MyCommand.Path "docs"; Read-Host "Press Enter to continue" }
379
+ "8" { Write-Host ""; & $MyInvocation.MyCommand.Path "uninstall" }
380
+ "0" { return }
381
+ default { Write-Host "Invalid option!" -ForegroundColor Red; Start-Sleep -Seconds 1 }
382
+ }
383
+ }
204
384
  }
205
385
 
206
386
  # Command handlers
package/bin/acadex.js CHANGED
@@ -7,6 +7,17 @@ const fs = require('fs');
7
7
 
8
8
  const platform = os.platform();
9
9
  const scriptDir = path.join(__dirname, '..');
10
+ const args = process.argv.slice(2);
11
+
12
+ // Check if menu command with no additional args - use interactive menu
13
+ if (args.length === 1 && args[0] === 'menu') {
14
+ const { startInteractiveMenu } = require('./interactive-menu');
15
+ startInteractiveMenu().catch(error => {
16
+ console.error('Error running interactive menu:', error.message);
17
+ process.exit(1);
18
+ });
19
+ return;
20
+ }
10
21
 
11
22
  let scriptPath;
12
23
  let shell;
@@ -29,7 +40,7 @@ if (platform === 'win32') {
29
40
  '-NoProfile',
30
41
  '-ExecutionPolicy', 'Bypass',
31
42
  '-File', scriptPath,
32
- ...process.argv.slice(2)
43
+ ...args
33
44
  ];
34
45
  } else if (platform === 'darwin' || platform === 'linux') {
35
46
  // macOS and Linux - use bash script
@@ -50,7 +61,7 @@ if (platform === 'win32') {
50
61
  }
51
62
 
52
63
  shell = 'bash';
53
- shellArgs = [scriptPath, ...process.argv.slice(2)];
64
+ shellArgs = [scriptPath, ...args];
54
65
  } else {
55
66
  // Unsupported platform
56
67
  console.error(`Error: Unsupported platform: ${platform}`);
@@ -0,0 +1,432 @@
1
+ #!/usr/bin/env node
2
+
3
+ const inquirer = require('inquirer');
4
+ const { spawn } = require('child_process');
5
+ const path = require('path');
6
+
7
+ // Get the script path based on platform
8
+ const getScriptPath = (platform) => {
9
+ const scriptDir = path.join(__dirname, '..');
10
+ if (platform === 'win32') {
11
+ return path.join(scriptDir, 'acadex.ps1');
12
+ }
13
+ return path.join(scriptDir, 'acadex');
14
+ };
15
+
16
+ // Execute command
17
+ const executeCommand = (command, platform) => {
18
+ return new Promise((resolve) => {
19
+ const scriptPath = getScriptPath(platform);
20
+ let shell, args;
21
+
22
+ if (platform === 'win32') {
23
+ shell = 'powershell.exe';
24
+ args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', scriptPath, command];
25
+ } else {
26
+ shell = 'bash';
27
+ args = [scriptPath, command];
28
+ }
29
+
30
+ const child = spawn(shell, args, { stdio: 'inherit' });
31
+
32
+ child.on('close', (code) => {
33
+ resolve(code);
34
+ });
35
+ });
36
+ };
37
+
38
+ // Main menu
39
+ const showMainMenu = async (platform) => {
40
+ const { category } = await inquirer.prompt([
41
+ {
42
+ type: 'list',
43
+ name: 'category',
44
+ message: '╔═══════════════════════════════════════╗\n║ ACADEX - Interactive Menu (v1.1) ║\n╚═══════════════════════════════════════╝\n\nSelect a category:',
45
+ choices: [
46
+ { name: '[+] Setup & Installation', value: 'setup' },
47
+ { name: '[>] Development', value: 'development' },
48
+ { name: '[✓] Testing', value: 'testing' },
49
+ { name: '[#] Database', value: 'database' },
50
+ { name: '[*] Maintenance', value: 'maintenance' },
51
+ { name: '[~] Code Quality', value: 'quality' },
52
+ { name: '[=] Dependencies', value: 'dependencies' },
53
+ { name: '[•] Other Commands', value: 'other' },
54
+ new inquirer.Separator(),
55
+ { name: '[X] Exit', value: 'exit' }
56
+ ],
57
+ pageSize: 15
58
+ }
59
+ ]);
60
+
61
+ if (category === 'exit') {
62
+ console.log('\n[✓] Goodbye!\n');
63
+ process.exit(0);
64
+ }
65
+
66
+ return category;
67
+ };
68
+
69
+ // Setup & Installation submenu
70
+ const showSetupMenu = async (platform) => {
71
+ const { command } = await inquirer.prompt([
72
+ {
73
+ type: 'list',
74
+ name: 'command',
75
+ message: '\n[+] Setup & Installation - Select command:',
76
+ choices: [
77
+ { name: 'setup - First-time full installation', value: 'setup' },
78
+ { name: 'install:2fa - Install 2FA packages', value: 'install:2fa' },
79
+ { name: 'install:notif - Install notification packages', value: 'install:notif' },
80
+ { name: 'check - Check system requirements', value: 'check' },
81
+ new inquirer.Separator(),
82
+ { name: '← Back to Main Menu', value: 'back' }
83
+ ]
84
+ }
85
+ ]);
86
+
87
+ if (command === 'back') return 'back';
88
+
89
+ await executeCommand(command, platform);
90
+
91
+ const { next } = await inquirer.prompt([
92
+ {
93
+ type: 'list',
94
+ name: 'next',
95
+ message: '\nWhat would you like to do next?',
96
+ choices: [
97
+ { name: '← Back to Setup & Installation menu', value: 'submenu' },
98
+ { name: '[H] Back to Main Menu', value: 'main' }
99
+ ]
100
+ }
101
+ ]);
102
+
103
+ return next === 'main' ? 'back' : 'repeat';
104
+ };
105
+
106
+ // Development submenu
107
+ const showDevelopmentMenu = async (platform) => {
108
+ const { command } = await inquirer.prompt([
109
+ {
110
+ type: 'list',
111
+ name: 'command',
112
+ message: '\n[>] Development - Select command:',
113
+ choices: [
114
+ { name: 'serve - Start production servers (Laravel + Queue + Scheduler + Reverb)', value: 'serve' },
115
+ { name: 'services - Start background services only (for Herd)', value: 'services' },
116
+ { name: 'dev - Start dev servers (Laravel + Queue + Logs + Vite + Reverb)', value: 'dev' },
117
+ { name: 'build - Build assets for production', value: 'build' },
118
+ { name: 'ui - Rebuild UI assets and clear caches', value: 'ui' },
119
+ { name: 'start - Start Laravel server only', value: 'start' },
120
+ new inquirer.Separator(),
121
+ { name: '← Back to Main Menu', value: 'back' }
122
+ ]
123
+ }
124
+ ]);
125
+
126
+ if (command === 'back') return 'back';
127
+
128
+ await executeCommand(command, platform);
129
+
130
+ const { next } = await inquirer.prompt([
131
+ {
132
+ type: 'list',
133
+ name: 'next',
134
+ message: '\nWhat would you like to do next?',
135
+ choices: [
136
+ { name: '← Back to Development menu', value: 'submenu' },
137
+ { name: '[H] Back to Main Menu', value: 'main' }
138
+ ]
139
+ }
140
+ ]);
141
+
142
+ return next === 'main' ? 'back' : 'repeat';
143
+ };
144
+
145
+ // Testing submenu
146
+ const showTestingMenu = async (platform) => {
147
+ const { command } = await inquirer.prompt([
148
+ {
149
+ type: 'list',
150
+ name: 'command',
151
+ message: '\n[✓] Testing - Select command:',
152
+ choices: [
153
+ { name: 'test - Run PHPUnit tests', value: 'test' },
154
+ { name: 'test:coverage - Run tests with coverage', value: 'test:coverage' },
155
+ new inquirer.Separator(),
156
+ { name: '← Back to Main Menu', value: 'back' }
157
+ ]
158
+ }
159
+ ]);
160
+
161
+ if (command === 'back') return 'back';
162
+
163
+ await executeCommand(command, platform);
164
+
165
+ const { next } = await inquirer.prompt([
166
+ {
167
+ type: 'list',
168
+ name: 'next',
169
+ message: '\nWhat would you like to do next?',
170
+ choices: [
171
+ { name: '← Back to Testing menu', value: 'submenu' },
172
+ { name: '[H] Back to Main Menu', value: 'main' }
173
+ ]
174
+ }
175
+ ]);
176
+
177
+ return next === 'main' ? 'back' : 'repeat';
178
+ };
179
+
180
+ // Database submenu
181
+ const showDatabaseMenu = async (platform) => {
182
+ const { command } = await inquirer.prompt([
183
+ {
184
+ type: 'list',
185
+ name: 'command',
186
+ message: '\n[#] Database - Select command:',
187
+ choices: [
188
+ { name: 'migrate - Run database migrations', value: 'migrate' },
189
+ { name: 'migrate:fresh - Fresh migration with seeders', value: 'migrate:fresh' },
190
+ { name: 'seed - Run database seeders', value: 'seed' },
191
+ { name: 'tinker - Start Laravel Tinker', value: 'tinker' },
192
+ new inquirer.Separator(),
193
+ { name: '← Back to Main Menu', value: 'back' }
194
+ ]
195
+ }
196
+ ]);
197
+
198
+ if (command === 'back') return 'back';
199
+
200
+ await executeCommand(command, platform);
201
+
202
+ if (command === 'tinker') return 'back';
203
+
204
+ const { next } = await inquirer.prompt([
205
+ {
206
+ type: 'list',
207
+ name: 'next',
208
+ message: '\nWhat would you like to do next?',
209
+ choices: [
210
+ { name: '← Back to Database menu', value: 'submenu' },
211
+ { name: '[H] Back to Main Menu', value: 'main' }
212
+ ]
213
+ }
214
+ ]);
215
+
216
+ return next === 'main' ? 'back' : 'repeat';
217
+ };
218
+
219
+ // Maintenance submenu
220
+ const showMaintenanceMenu = async (platform) => {
221
+ const { command } = await inquirer.prompt([
222
+ {
223
+ type: 'list',
224
+ name: 'command',
225
+ message: '\n[*] Maintenance - Select command:',
226
+ choices: [
227
+ { name: 'cache:clear - Clear all caches', value: 'cache:clear' },
228
+ { name: 'optimize - Optimize the application', value: 'optimize' },
229
+ { name: 'logs - Tail Laravel logs', value: 'logs' },
230
+ new inquirer.Separator(),
231
+ { name: '← Back to Main Menu', value: 'back' }
232
+ ]
233
+ }
234
+ ]);
235
+
236
+ if (command === 'back') return 'back';
237
+
238
+ await executeCommand(command, platform);
239
+
240
+ if (command === 'logs') return 'back';
241
+
242
+ const { next } = await inquirer.prompt([
243
+ {
244
+ type: 'list',
245
+ name: 'next',
246
+ message: '\nWhat would you like to do next?',
247
+ choices: [
248
+ { name: '← Back to Maintenance menu', value: 'submenu' },
249
+ { name: '[H] Back to Main Menu', value: 'main' }
250
+ ]
251
+ }
252
+ ]);
253
+
254
+ return next === 'main' ? 'back' : 'repeat';
255
+ };
256
+
257
+ // Code Quality submenu
258
+ const showQualityMenu = async (platform) => {
259
+ const { command } = await inquirer.prompt([
260
+ {
261
+ type: 'list',
262
+ name: 'command',
263
+ message: '\n[~] Code Quality - Select command:',
264
+ choices: [
265
+ { name: 'analyze - Run PHPStan static analysis', value: 'analyze' },
266
+ { name: 'format - Format code with Pint', value: 'format' },
267
+ new inquirer.Separator(),
268
+ { name: '← Back to Main Menu', value: 'back' }
269
+ ]
270
+ }
271
+ ]);
272
+
273
+ if (command === 'back') return 'back';
274
+
275
+ await executeCommand(command, platform);
276
+
277
+ const { next } = await inquirer.prompt([
278
+ {
279
+ type: 'list',
280
+ name: 'next',
281
+ message: '\nWhat would you like to do next?',
282
+ choices: [
283
+ { name: '← Back to Code Quality menu', value: 'submenu' },
284
+ { name: '[H] Back to Main Menu', value: 'main' }
285
+ ]
286
+ }
287
+ ]);
288
+
289
+ return next === 'main' ? 'back' : 'repeat';
290
+ };
291
+
292
+ // Dependencies submenu
293
+ const showDependenciesMenu = async (platform) => {
294
+ const { command } = await inquirer.prompt([
295
+ {
296
+ type: 'list',
297
+ name: 'command',
298
+ message: '\n[=] Dependencies - Select command:',
299
+ choices: [
300
+ { name: 'install - Install all dependencies', value: 'install' },
301
+ { name: 'update - Update all dependencies', value: 'update' },
302
+ new inquirer.Separator(),
303
+ { name: '← Back to Main Menu', value: 'back' }
304
+ ]
305
+ }
306
+ ]);
307
+
308
+ if (command === 'back') return 'back';
309
+
310
+ await executeCommand(command, platform);
311
+
312
+ const { next } = await inquirer.prompt([
313
+ {
314
+ type: 'list',
315
+ name: 'next',
316
+ message: '\nWhat would you like to do next?',
317
+ choices: [
318
+ { name: '← Back to Dependencies menu', value: 'submenu' },
319
+ { name: '[H] Back to Main Menu', value: 'main' }
320
+ ]
321
+ }
322
+ ]);
323
+
324
+ return next === 'main' ? 'back' : 'repeat';
325
+ };
326
+
327
+ // Other Commands submenu
328
+ const showOtherMenu = async (platform) => {
329
+ const { command } = await inquirer.prompt([
330
+ {
331
+ type: 'list',
332
+ name: 'command',
333
+ message: '\n[•] Other Commands - Select command:',
334
+ choices: [
335
+ { name: 'routes - List all routes', value: 'routes' },
336
+ { name: 'queue - Start queue worker', value: 'queue' },
337
+ { name: 'schedule - Run scheduled tasks', value: 'schedule' },
338
+ { name: 'share - Share site publicly via Expose', value: 'share' },
339
+ { name: 'phpmyadmin - Start Apache & open phpMyAdmin', value: 'phpmyadmin' },
340
+ { name: 'phpmyadmin:stop - Stop Apache', value: 'phpmyadmin:stop' },
341
+ { name: 'docs - Open ACADEX documentation', value: 'docs' },
342
+ new inquirer.Separator(),
343
+ { name: '← Back to Main Menu', value: 'back' }
344
+ ]
345
+ }
346
+ ]);
347
+
348
+ if (command === 'back') return 'back';
349
+
350
+ await executeCommand(command, platform);
351
+
352
+ if (['queue', 'share'].includes(command)) return 'back';
353
+
354
+ const { next } = await inquirer.prompt([
355
+ {
356
+ type: 'list',
357
+ name: 'next',
358
+ message: '\nWhat would you like to do next?',
359
+ choices: [
360
+ { name: '← Back to Other Commands menu', value: 'submenu' },
361
+ { name: '[H] Back to Main Menu', value: 'main' }
362
+ ]
363
+ }
364
+ ]);
365
+
366
+ return next === 'main' ? 'back' : 'repeat';
367
+ };
368
+
369
+ // Main interactive loop
370
+ const startInteractiveMenu = async () => {
371
+ const platform = require('os').platform();
372
+
373
+ while (true) {
374
+ const category = await showMainMenu(platform);
375
+
376
+ if (category === 'exit') {
377
+ console.log('\nGoodbye! 👋');
378
+ process.exit(0);
379
+ }
380
+
381
+ // Stay in the submenu until user explicitly chooses to go back
382
+ let shouldReturn = false;
383
+ while (!shouldReturn) {
384
+ let result;
385
+ switch (category) {
386
+ case 'setup':
387
+ result = await showSetupMenu(platform);
388
+ break;
389
+ case 'development':
390
+ result = await showDevelopmentMenu(platform);
391
+ break;
392
+ case 'testing':
393
+ result = await showTestingMenu(platform);
394
+ break;
395
+ case 'database':
396
+ result = await showDatabaseMenu(platform);
397
+ break;
398
+ case 'maintenance':
399
+ result = await showMaintenanceMenu(platform);
400
+ break;
401
+ case 'quality':
402
+ result = await showQualityMenu(platform);
403
+ break;
404
+ case 'dependencies':
405
+ result = await showDependenciesMenu(platform);
406
+ break;
407
+ case 'other':
408
+ result = await showOtherMenu(platform);
409
+ break;
410
+ default:
411
+ shouldReturn = true;
412
+ break;
413
+ }
414
+
415
+ // If submenu returns 'back', exit to main menu
416
+ if (result === 'back') {
417
+ shouldReturn = true;
418
+ }
419
+ // If submenu returns 'repeat', stay in submenu
420
+ }
421
+ }
422
+ };
423
+
424
+ module.exports = { startInteractiveMenu };
425
+
426
+ // Run if called directly
427
+ if (require.main === module) {
428
+ startInteractiveMenu().catch(error => {
429
+ console.error('Error:', error.message);
430
+ process.exit(1);
431
+ });
432
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acadex-cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A global CLI tool for managing Acadex projects with easy setup and automation",
5
5
  "main": "bin/acadex.js",
6
6
  "bin": {
@@ -33,6 +33,9 @@
33
33
  "node": ">=14.0.0"
34
34
  },
35
35
  "preferGlobal": true,
36
+ "dependencies": {
37
+ "inquirer": "^8.2.6"
38
+ },
36
39
  "os": [
37
40
  "darwin",
38
41
  "linux",