@@ -2,7 +2,17 @@ import { resolve } from 'node:path'
22import { promises as fs } from 'node:fs'
33import type { NetlifyAPI } from '@netlify/api'
44
5- import { chalk , log , logAndThrowError , type APIError } from '../../utils/command-helpers.js'
5+ import {
6+ chalk ,
7+ log ,
8+ logPadded ,
9+ logAndThrowError ,
10+ type APIError ,
11+ NETLIFY_CYAN ,
12+ NETLIFYDEVLOG ,
13+ NETLIFYDEVWARN ,
14+ NETLIFYDEVERR ,
15+ } from '../../utils/command-helpers.js'
616import { normalizeRepoUrl } from '../../utils/normalize-repo-url.js'
717import { runGit } from '../../utils/run-git.js'
818import { startSpinner } from '../../lib/spinner.js'
@@ -19,6 +29,10 @@ import type BaseCommand from '../base-command.js'
1929import type { SiteInfo } from '../../utils/types.js'
2030import inquirer from 'inquirer'
2131
32+ const SPARK_URL = process . env . SPARK_URL ?? 'https://spark.netlify.app'
33+ const AI_SITE_PROMPT_GEN_URL = `${ SPARK_URL } /site-prompt-gen`
34+ const DOCS_URL = process . env . DOCS_URL ?? 'https://docs.netlify.com'
35+
2236/**
2337 * Project information interface for AI projects
2438 */
@@ -30,7 +44,7 @@ interface ProjectInfo {
3044
3145// Trigger IDE-specific MCP configuration
3246const triggerMcpConfiguration = async ( ide : ConsumerConfig , projectPath : string ) : Promise < boolean > => {
33- log ( `\n${ chalk . blue ( '🔧 MCP Configuration for' ) } ${ chalk . cyan ( ide . presentedName ) } ` )
47+ log ( `\n${ chalk . blue ( '🔧 MCP Configuration for' ) } ${ NETLIFY_CYAN ( ide . presentedName ) } ` )
3448
3549 const { shouldConfigure } = await inquirer . prompt < { shouldConfigure : boolean } > ( [
3650 {
@@ -42,9 +56,9 @@ const triggerMcpConfiguration = async (ide: ConsumerConfig, projectPath: string)
4256 ] )
4357
4458 if ( ! shouldConfigure ) {
45- log ( ` ${ chalk . gray ( 'You can configure MCP manually later for enhanced AI capabilities:' ) } ` )
59+ log ( ` ${ chalk . dim ( 'You can configure MCP manually later for enhanced AI capabilities:' ) } ` )
4660 log (
47- ` ${ chalk . gray ( 'Documentation:' ) } ${ chalk . cyan (
61+ ` ${ chalk . dim ( 'Documentation:' ) } ${ NETLIFY_CYAN (
4862 'https://docs.netlify.com/welcome/build-with-ai/netlify-mcp-server/' ,
4963 ) } `,
5064 )
@@ -70,23 +84,14 @@ const triggerMcpConfiguration = async (ide: ConsumerConfig, projectPath: string)
7084 showGenericMcpConfig ( config , ide . presentedName )
7185 }
7286
73- log ( `${ chalk . green ( '✅' ) } MCP configuration completed for ${ chalk . cyan ( ide . presentedName ) } ` )
87+ log ( `${ NETLIFYDEVLOG } MCP configuration completed for ${ NETLIFY_CYAN ( ide . presentedName ) } ` )
7488 return true
7589 } catch ( error ) {
76- log ( `${ chalk . red ( '❌' ) } Failed to configure MCP: ${ error instanceof Error ? error . message : 'Unknown error' } ` )
90+ log ( `${ NETLIFYDEVERR } Failed to configure MCP: ${ error instanceof Error ? error . message : 'Unknown error' } ` )
7791 return false
7892 }
7993}
8094
81- // Helper functions reused from ai-start.ts
82- const decodeHash = ( hash : string ) : string => {
83- try {
84- return atob ( hash )
85- } catch ( error ) {
86- throw new Error ( `Failed to decode hash: ${ error instanceof Error ? error . message : 'Invalid base64 or URL' } ` )
87- }
88- }
89-
9095const fetchProjectInfo = async ( url : string ) : Promise < ProjectInfo > => {
9196 try {
9297 const response = await fetch ( url , {
@@ -125,10 +130,10 @@ const savePrompt = async (instructions: string, ntlContext: string | null, targe
125130 try {
126131 const filePath = resolve ( targetDir , 'AI-instructions.md' )
127132 await fs . writeFile ( filePath , `Context: ${ ntlContext ?? '' } \n\n${ instructions } ` , 'utf-8' )
128- log ( `${ chalk . green ( '✅' ) } AI instructions saved to ${ chalk . cyan ( 'AI-instructions.md' ) } ` )
133+ log ( `${ NETLIFYDEVLOG } AI instructions saved to ${ NETLIFY_CYAN ( 'AI-instructions.md' ) } ` )
129134 } catch ( error ) {
130135 const errorMessage = error instanceof Error ? error . message : 'Unknown error'
131- log ( `${ chalk . yellow ( '⚠️' ) } Warning: Failed to save AI instructions: ${ errorMessage } ` )
136+ log ( `${ NETLIFYDEVWARN } Warning: Failed to save AI instructions: ${ errorMessage } ` )
132137 }
133138}
134139
@@ -149,45 +154,34 @@ export const initWithAiRules = async (hash: string, command: BaseCommand): Promi
149154 await command . authenticate ( )
150155 const { api } = command . netlify
151156
152- log ( `${ chalk . blue ( '🤖 Initializing AI project' ) } with rules...` )
153- log ( `${ chalk . gray ( 'User:' ) } ${ api . accessToken ? 'Authenticated ✅' : 'Not authenticated ❌' } ` )
157+ log ( `${ NETLIFY_CYAN ( '🤖 Initializing AI project' ) } with rules...` )
158+ log ( `${ NETLIFY_CYAN ( 'User:' ) } ${ api . accessToken ? 'Authenticated ✅' : 'Not authenticated ❌' } ` )
154159
155160 try {
156161 // Step 1: Decode hash and fetch project information
157162 log ( '\n📋 Extracting project details...' )
158- const decodedUrl = decodeHash ( hash )
159- log ( `${ chalk . cyan ( 'Decoded URL:' ) } ${ decodedUrl } ` )
163+ const decodedUrl = ` ${ AI_SITE_PROMPT_GEN_URL } / ${ hash } `
164+ log ( `${ NETLIFY_CYAN ( 'Decoded URL:' ) } ${ decodedUrl } ` )
160165
161166 log ( '\n🔍 Fetching project information...' )
162167 const projectInfo = await fetchProjectInfo ( decodedUrl )
163168
164- log ( `${ chalk . cyan ( 'Project ID:' ) } ${ projectInfo . projectId } ` )
165-
166169 // Step 2: Get repository URL from project ID via Netlify site API
167170 log ( '\n🔗 Linking to Netlify project and fetching repository...' )
168171 const repositoryUrl = await getRepoUrlFromProjectId ( api , projectInfo . projectId )
169- log ( `${ chalk . cyan ( 'Repository:' ) } ${ repositoryUrl } ` )
170172
171173 // Step 3: Clone repository
172174 const { repoUrl, repoName } = normalizeRepoUrl ( repositoryUrl )
173175 const targetDir = `ai-project-${ repoName } -${ hash . substring ( 0 , 8 ) } `
174176
175- const cloneSpinner = startSpinner ( { text : `Cloning repository to ${ chalk . cyan ( targetDir ) } ` } )
177+ const cloneSpinner = startSpinner ( { text : `Cloning repository to ${ NETLIFY_CYAN ( targetDir ) } ` } )
176178
177179 await cloneRepo ( repoUrl , targetDir , false )
178- cloneSpinner . success ( { text : `Cloned repository to ${ chalk . cyan ( targetDir ) } ` } )
180+ cloneSpinner . success ( { text : `Cloned repository to ${ NETLIFY_CYAN ( targetDir ) } ` } )
179181
180182 // Step 4: Save AI instructions to file
181183 if ( projectInfo . prompt ) {
182- const ntlContext = await fetch (
183- 'https://docs.netlify.com/ai-context/scoped-context?scopes=serverless,blobs,forms' ,
184- {
185- method : 'GET' ,
186- headers : {
187- 'Content-Type' : 'text/plain' ,
188- } ,
189- } ,
190- )
184+ const ntlContext = await fetch ( `${ DOCS_URL } /ai-context/scoped-context?scopes=serverless,blobs,forms` )
191185 . then ( ( res ) => res . text ( ) )
192186 . catch ( ( ) => {
193187 return null
@@ -202,7 +196,7 @@ export const initWithAiRules = async (hash: string, command: BaseCommand): Promi
202196 let mcpConfigured = false
203197
204198 if ( detectedIDE ) {
205- log ( `${ chalk . green ( '✅' ) } Detected development environment: ${ chalk . cyan ( detectedIDE . presentedName ) } ` )
199+ log ( `${ NETLIFYDEVLOG } Detected development environment: ${ NETLIFY_CYAN ( detectedIDE . presentedName ) } ` )
206200 mcpConfigured = await triggerMcpConfiguration ( detectedIDE , targetDir )
207201 }
208202
@@ -212,28 +206,27 @@ export const initWithAiRules = async (hash: string, command: BaseCommand): Promi
212206
213207 // Success message with next steps
214208 log ( )
215- log ( chalk . green ( '✔ Your AI project is ready to go!' ) )
216- log ( `→ Project ID: ${ chalk . cyanBright ( projectInfo . projectId ) } ` )
217- log ( `→ Project cloned to: ${ chalk . cyanBright ( targetDir ) } ` )
209+ log ( `${ NETLIFYDEVLOG } Your AI project is ready to go!` )
210+ log ( `→ Project cloned to: ${ NETLIFY_CYAN ( targetDir ) } ` )
218211 if ( projectInfo . prompt ) {
219- log ( `→ AI instructions saved: ${ chalk . cyanBright ( 'AI-instructions.md' ) } ` )
212+ log ( `→ AI instructions saved: ${ NETLIFY_CYAN ( 'AI-instructions.md' ) } ` )
220213 }
221214 log ( )
222- log ( chalk . yellowBright ( `📁 Step 1: Enter your project directory`) )
223- log ( ` ${ chalk . cyanBright ( `cd ${ targetDir } ` ) } ` )
215+ log ( ` ${ NETLIFYDEVWARN } Step 1: Enter your project directory`)
216+ log ( ` ${ NETLIFY_CYAN ( `cd ${ targetDir } ` ) } ` )
224217
225218 if ( detectedIDE ) {
226219 if ( mcpConfigured ) {
227- log ( chalk . yellowBright ( `🔧 Step 2: MCP Server Configured`) )
228- log ( ` ${ chalk . green ( '✅' ) } ${ chalk . cyan ( detectedIDE . key ) } is ready with Netlify MCP server` )
229- log ( ` ${ chalk . gray ( '💡 MCP will activate when you reload/restart your development environment' ) } ` )
220+ log ( ` ${ NETLIFYDEVWARN } Step 2: MCP Server Configured`)
221+ log ( ` ${ NETLIFYDEVLOG } ${ NETLIFY_CYAN ( detectedIDE . key ) } is ready with Netlify MCP server` )
222+ log ( ` ${ chalk . dim ( '💡 MCP will activate when you reload/restart your development environment' ) } ` )
230223 } else {
231- log ( chalk . yellowBright ( `🔧 Step 2: Manual MCP Configuration`) )
232- log ( ` ${ chalk . cyan ( detectedIDE . key ) } detected - MCP setup was skipped` )
233- log ( ` ${ chalk . gray ( 'You can configure MCP manually later for enhanced AI capabilities:' ) } ` )
224+ log ( ` ${ NETLIFYDEVWARN } Step 2: Manual MCP Configuration`)
225+ log ( ` ${ NETLIFY_CYAN ( detectedIDE . key ) } detected - MCP setup was skipped` )
226+ log ( ` ${ chalk . dim ( 'You can configure MCP manually later for enhanced AI capabilities:' ) } ` )
234227 log (
235- ` ${ chalk . gray ( 'Documentation:' ) } ${ chalk . cyan (
236- 'https://docs.netlify.com/ welcome/build-with-ai/netlify-mcp-server/' ,
228+ ` ${ chalk . dim ( 'Documentation:' ) } ${ NETLIFY_CYAN (
229+ ` ${ DOCS_URL } / welcome/build-with-ai/netlify-mcp-server/` ,
237230 ) } `,
238231 )
239232 }
@@ -242,11 +235,9 @@ export const initWithAiRules = async (hash: string, command: BaseCommand): Promi
242235
243236 if ( projectInfo . prompt ) {
244237 const stepNumber = detectedIDE ? '3' : '2'
245- log ( chalk . yellowBright ( `🤖 Step ${ stepNumber } : Ask your AI assistant to process the instructions`) )
238+ log ( ` ${ NETLIFYDEVWARN } Step ${ stepNumber } : Ask your AI assistant to process the instructions`)
246239 log ( )
247- log ( chalk . gray ( '*' . repeat ( 60 ) ) )
248- log ( chalk . cyan ( `Follow ${ targetDir } /AI-instructions.md and create a new site` ) )
249- log ( chalk . gray ( '*' . repeat ( 60 ) ) )
240+ logPadded ( NETLIFY_CYAN ( `Follow ${ targetDir } /AI-instructions.md and create a new site` ) )
250241 log ( )
251242 }
252243 } catch ( error ) {
0 commit comments