99use Illuminate \Support \Collection ;
1010use Illuminate \Support \Facades \Artisan ;
1111use Illuminate \Support \Str ;
12+ use Laravel \Boost \Contracts \Agent ;
13+ use Laravel \Boost \Contracts \Ide ;
1214use Laravel \Boost \Install \Cli \DisplayHelper ;
1315use Laravel \Boost \Install \CodeEnvironmentsDetector ;
1416use Laravel \Boost \Install \GuidelineComposer ;
2527use function Laravel \Prompts \multiselect ;
2628use function Laravel \Prompts \note ;
2729use function Laravel \Prompts \select ;
28- use function Laravel \Prompts \text ;
2930
3031#[AsCommand('boost:install ' , 'Install Laravel Boost ' )]
3132class InstallCommand extends Command
@@ -40,27 +41,23 @@ class InstallCommand extends Command
4041
4142 private Terminal $ terminal ;
4243
43- /** @var Collection<int, \Laravel\Boost\Contracts\ Agent> */
44+ /** @var Collection<int, Agent> */
4445 private Collection $ agentsToInstallTo ;
4546
46- /** @var Collection<int, \Laravel\Boost\Contracts\ Ide> */
47+ /** @var Collection<int, Ide> */
4748 private Collection $ idesToInstallTo ;
4849
4950 private Collection $ boostToInstall ;
5051
5152 private string $ projectName ;
5253
53- private string $ projectPurpose = '' ;
54-
5554 /** @var array<non-empty-string> */
5655 private array $ systemInstalledCodeEnvironments = [];
5756
5857 private array $ projectInstalledCodeEnvironments = [];
5958
6059 private bool $ enforceTests = true ;
6160
62- private array $ boostToolsToDisable = [];
63-
6461 private array $ projectInstalledAgents = [];
6562
6663 private string $ greenTick ;
@@ -73,7 +70,7 @@ public function handle(CodeEnvironmentsDetector $codeEnvironmentsDetector, Herd
7370
7471 $ this ->displayBoostHeader ();
7572 $ this ->discoverEnvironment ();
76- $ this ->query ();
73+ $ this ->collectInstallationPreference ();
7774 $ this ->enact ();
7875 $ this ->outro ();
7976 }
@@ -122,17 +119,12 @@ private function discoverEnvironment(): void
122119 $ this ->projectInstalledAgents = $ this ->codeEnvironmentsDetector ->discoverProjectInstalledCodeEnvironments (base_path ());
123120 }
124121
125- private function query ()
122+ private function collectInstallationPreference (): void
126123 {
127- // Which parts of boost should we install
128- $ this ->boostToInstall = $ this ->boostToInstall ();
129- // $this->boostToolsToDisable = $this->boostToolsToDisable(); // Not useful to start
130-
131- // $this->projectPurpose = $this->projectPurpose();
132- $ this ->enforceTests = $ this ->shouldEnforceTests (ask: false );
133-
134- $ this ->idesToInstallTo = $ this ->idesToInstallTo (); // To add boost:mcp to the correct file
135- $ this ->agentsToInstallTo = $ this ->agentsToInstallTo (); // AI Guidelines, which file do they go, are they separated, or all in one file?
124+ $ this ->boostToInstall = $ this ->selectBoostFeatures ();
125+ $ this ->enforceTests = $ this ->determineTestEnforcement (ask: false );
126+ $ this ->idesToInstallTo = $ this ->selectTargetIdes ();
127+ $ this ->agentsToInstallTo = $ this ->selectTargetAgents ();
136128 }
137129
138130 private function enact (): void
@@ -210,45 +202,38 @@ private function hyperlink(string $label, string $url): string
210202 return "\033]8;; {$ url }\007{$ label }\033]8;; \033\\" ;
211203 }
212204
213- protected function projectPurpose (): string
214- {
215- return text (
216- label: sprintf ('What does the %s project do? (optional) ' , $ this ->projectName ),
217- placeholder: 'i.e. SaaS platform selling concert tickets, integrates with Stripe and Twilio, lots of CS using Nova backend ' ,
218- default: config ('boost.project_purpose ' ) ?? '' ,
219- hint: 'This helps guides AI. How would you explain it to a new developer? '
220- );
221- }
222-
223205 /**
224206 * We shouldn't add an AI guideline enforcing tests if they don't have a basic test setup.
225- * This would likely just create headaches for them, or be a waste of time as they
207+ * This would likely just create headaches for them or be a waste of time as they
226208 * won't have the CI setup to make use of them anyway, so we're just wasting their
227209 * tokens/money by enforcing them.
210+ *
211+ * @param bool $ask
212+ * @return bool
228213 */
229- protected function shouldEnforceTests (bool $ ask = true ): bool
214+ protected function determineTestEnforcement (bool $ ask = true ): bool
230215 {
231- $ enforce = Finder::create ()
216+ $ hasMinimumTests = Finder::create ()
232217 ->in (base_path ('tests ' ))
233218 ->files ()
234219 ->name ('*.php ' )
235220 ->count () > 6 ;
236221
237- if ($ enforce === false && $ ask === true ) {
238- $ enforce = select (
222+ if (! $ hasMinimumTests && ! $ ask ) {
223+ $ hasMinimumTests = select (
239224 label: 'Should AI always create tests? ' ,
240225 options: ['Yes ' , 'No ' ],
241226 default: 'Yes '
242227 ) === 'Yes ' ;
243228 }
244229
245- return $ enforce ;
230+ return $ hasMinimumTests ;
246231 }
247232
248233 /**
249234 * @return Collection<int, string>
250235 */
251- protected function boostToInstall (): Collection
236+ private function selectBoostFeatures (): Collection
252237 {
253238 $ defaultToInstallOptions = ['mcp_server ' , 'ai_guidelines ' ];
254239 $ toInstallOptions = [
@@ -316,9 +301,9 @@ private function discoverProjectAgents(): array
316301 }
317302
318303 /**
319- * @return Collection<int, \Laravel\Boost\Contracts\ Ide>
304+ * @return Collection<int, Ide>
320305 */
321- private function idesToInstallTo (): Collection
306+ private function selectTargetIdes (): Collection
322307 {
323308 $ ides = [];
324309 if (! $ this ->installingMcp () && ! $ this ->installingHerdMcp ()) {
@@ -338,7 +323,7 @@ private function idesToInstallTo(): Collection
338323 if (class_exists ($ className )) {
339324 $ reflection = new \ReflectionClass ($ className );
340325
341- if ($ reflection ->implementsInterface (\ Laravel \ Boost \ Contracts \ Ide::class) && ! $ reflection ->isAbstract ()) {
326+ if ($ reflection ->implementsInterface (Ide::class) && ! $ reflection ->isAbstract ()) {
342327 $ ides [$ className ] = Str::headline ($ ideFile ->getBasename ('.php ' ));
343328 }
344329 }
@@ -370,9 +355,9 @@ private function idesToInstallTo(): Collection
370355 }
371356
372357 /**
373- * @return Collection<int, \Laravel\Boost\Contracts\ Agent>
358+ * @return Collection<int, Agent>
374359 */
375- private function agentsToInstallTo (): Collection
360+ private function selectTargetAgents (): Collection
376361 {
377362 $ agents = [];
378363 if (! $ this ->installingGuidelines ()) {
@@ -392,7 +377,7 @@ private function agentsToInstallTo(): Collection
392377 if (class_exists ($ className )) {
393378 $ reflection = new \ReflectionClass ($ className );
394379
395- if ($ reflection ->implementsInterface (\ Laravel \ Boost \ Contracts \ Agent::class)) {
380+ if ($ reflection ->implementsInterface (Agent::class)) {
396381 $ agents [$ className ] = Str::headline ($ agentFile ->getBasename ('.php ' ));
397382 }
398383 }
0 commit comments