11#!/usr/bin/env node
22
33import { parsePackageJson } from './src/parser.js' ;
4- import { showHeader , showScriptMenu , showExecutionOptions , showBackgroundProcessOptions , showError , showSuccess , showInfo , showLogs , clearScreen } from './src/ui.js' ;
4+ import { showHeader , showScriptMenu , showScriptMenuWithHistory , showExecutionOptions , showBackgroundProcessOptions , showWorkspaceMenu , showMonorepoHeader , showError , showSuccess , showInfo , showLogs , clearScreen } from './src/ui.js' ;
55import { runScript , runScriptBackground , getScriptCommand , copyToClipboard , killProcess , isProcessRunning } from './src/runner.js' ;
6+ import { addToHistory , getRecentScripts } from './src/history.js' ;
7+ import { detectMonorepo , findWorkspaces , isMonorepo } from './src/monorepo.js' ;
8+ import { toggleFavorite , isFavorite , getFavorites } from './src/favorites.js' ;
69
710const backgroundProcesses = [ ] ;
811
@@ -70,14 +73,54 @@ async function main() {
7073 }
7174
7275 try {
73- const { scripts, scriptsDescriptions, projectName } = await parsePackageJson ( options . directory ) ;
76+ const rootPkg = await parsePackageJson ( options . directory ) ;
77+ const monorepoConfig = await detectMonorepo ( options . directory ) ;
78+
79+ // Handle monorepo workspace selection
80+ let currentDirectory = options . directory ;
81+ let currentProject = rootPkg ;
82+ let workspaceName = null ;
83+
84+ if ( isMonorepo ( monorepoConfig ) && ! options . scriptName && ! options . list ) {
85+ const workspaces = await findWorkspaces ( monorepoConfig ) ;
86+
87+ if ( workspaces . length > 0 ) {
88+ showHeader ( rootPkg . projectName ) ;
89+ showInfo ( `Monorepo detectado (${ monorepoConfig . type } ) - ${ workspaces . length } workspace(s)` ) ;
90+
91+ const selectedWorkspace = await showWorkspaceMenu ( workspaces , rootPkg . projectName ) ;
92+
93+ if ( selectedWorkspace === 'exit' ) {
94+ showSuccess ( 'Até mais!' ) ;
95+ process . exit ( 0 ) ;
96+ }
97+
98+ if ( selectedWorkspace !== 'root' ) {
99+ currentDirectory = selectedWorkspace . path ;
100+ currentProject = {
101+ scripts : selectedWorkspace . scripts ,
102+ scriptsDescriptions : selectedWorkspace . scriptsDescriptions ,
103+ projectName : selectedWorkspace . name ,
104+ } ;
105+ workspaceName = selectedWorkspace . name ;
106+ }
107+
108+ clearScreen ( ) ;
109+ }
110+ }
111+
112+ const { scripts, scriptsDescriptions, projectName } = currentProject ;
74113
75114 if ( Object . keys ( scripts ) . length === 0 ) {
76115 showError ( 'Nenhum script encontrado no package.json' ) ;
77116 process . exit ( 1 ) ;
78117 }
79118
80- showHeader ( projectName ) ;
119+ if ( workspaceName ) {
120+ showMonorepoHeader ( rootPkg . projectName , workspaceName ) ;
121+ } else {
122+ showHeader ( projectName ) ;
123+ }
81124
82125 if ( options . list ) {
83126 console . log ( '\nScripts disponíveis:\n' ) ;
@@ -94,7 +137,8 @@ async function main() {
94137 showError ( `Script "${ options . scriptName } " não encontrado` ) ;
95138 process . exit ( 1 ) ;
96139 }
97- await runScript ( options . scriptName , options . directory ) ;
140+ await addToHistory ( { script : options . scriptName , directory : currentDirectory , projectName } ) ;
141+ await runScript ( options . scriptName , currentDirectory ) ;
98142 process . exit ( 0 ) ;
99143 }
100144
@@ -110,11 +154,19 @@ async function main() {
110154 // Refresh screen if needed
111155 if ( needsRefresh ) {
112156 clearScreen ( ) ;
113- showHeader ( projectName ) ;
157+ if ( workspaceName ) {
158+ showMonorepoHeader ( rootPkg . projectName , workspaceName ) ;
159+ } else {
160+ showHeader ( projectName ) ;
161+ }
114162 needsRefresh = false ;
115163 }
116164
117- const selected = await showScriptMenu ( scripts , scriptsDescriptions , backgroundProcesses ) ;
165+ // Get recent scripts and favorites for this directory
166+ const recentScripts = await getRecentScripts ( currentDirectory , 3 ) ;
167+ const favorites = await getFavorites ( currentDirectory ) ;
168+
169+ const selected = await showScriptMenuWithHistory ( scripts , scriptsDescriptions , backgroundProcesses , recentScripts , favorites ) ;
118170
119171 if ( selected === 'exit' ) {
120172 if ( backgroundProcesses . length > 0 ) {
@@ -130,13 +182,21 @@ async function main() {
130182
131183 while ( true ) {
132184 clearScreen ( ) ;
133- showHeader ( projectName ) ;
185+ if ( workspaceName ) {
186+ showMonorepoHeader ( rootPkg . projectName , workspaceName ) ;
187+ } else {
188+ showHeader ( projectName ) ;
189+ }
134190
135191 const procOption = await showBackgroundProcessOptions ( proc || selected ) ;
136192
137193 if ( procOption === 'logs' && proc ) {
138194 clearScreen ( ) ;
139- showHeader ( projectName ) ;
195+ if ( workspaceName ) {
196+ showMonorepoHeader ( rootPkg . projectName , workspaceName ) ;
197+ } else {
198+ showHeader ( projectName ) ;
199+ }
140200 await showLogs ( proc ) ;
141201 } else if ( procOption === 'kill' ) {
142202 const killed = killProcess ( selected . pid ) ;
@@ -154,22 +214,33 @@ async function main() {
154214 continue ;
155215 }
156216
157- const execOption = await showExecutionOptions ( selected ) ;
217+ const isScriptFavorite = await isFavorite ( selected , currentDirectory ) ;
218+ const execOption = await showExecutionOptions ( selected , isScriptFavorite ) ;
158219
159220 if ( execOption === 'back' ) {
160221 needsRefresh = true ;
161222 continue ;
162223 }
163224
164- if ( execOption === 'interactive' ) {
165- await runScript ( selected , options . directory ) ;
225+ if ( execOption === 'favorite' ) {
226+ const nowFavorite = await toggleFavorite ( { script : selected , directory : currentDirectory , projectName } ) ;
227+ if ( nowFavorite ) {
228+ showSuccess ( `"${ selected } " adicionado aos favoritos` ) ;
229+ } else {
230+ showInfo ( `"${ selected } " removido dos favoritos` ) ;
231+ }
232+ needsRefresh = true ;
233+ } else if ( execOption === 'interactive' ) {
234+ await addToHistory ( { script : selected , directory : currentDirectory , projectName } ) ;
235+ await runScript ( selected , currentDirectory ) ;
166236 needsRefresh = true ;
167237 } else if ( execOption === 'background' ) {
168- const result = runScriptBackground ( selected , options . directory ) ;
238+ await addToHistory ( { script : selected , directory : currentDirectory , projectName } ) ;
239+ const result = runScriptBackground ( selected , currentDirectory ) ;
169240 backgroundProcesses . push ( { name : selected , pid : result . pid , logs : result . logs } ) ;
170241 needsRefresh = true ;
171242 } else if ( execOption === 'copy' ) {
172- const command = getScriptCommand ( selected , options . directory ) ;
243+ const command = getScriptCommand ( selected , currentDirectory ) ;
173244 try {
174245 await copyToClipboard ( command ) ;
175246 showSuccess ( `Comando copiado: ${ command } ` ) ;
0 commit comments