@@ -21,7 +21,8 @@ const archiver = require('archiver');
2121const PROJECT_ROOT = path . dirname ( __dirname ) ;
2222const BUILD_DIR = path . join ( PROJECT_ROOT , 'build' ) ;
2323
24- const SITE_URL = process . env . SITE_URL || 'https://bmad-code-org.github.io/BMAD-METHOD' ;
24+ // For local builds, use localhost. Production URL set via SITE_URL env var in CI.
25+ const SITE_URL = process . env . SITE_URL || 'http://localhost:4321' ;
2526const REPO_URL = 'https://github.com/bmad-code-org/BMAD-METHOD' ;
2627
2728const LLM_MAX_CHARS = 600_000 ;
@@ -108,15 +109,55 @@ function buildAstroSite() {
108109 runAstroBuild ( ) ;
109110 copyArtifactsToSite ( artifactsDir , siteDir ) ;
110111
111- // No longer needed: Inject AI agents banner into every HTML page
112- // injectAgentBanner (siteDir);
112+ // Verify all links in built site
113+ verifyBuiltLinks ( siteDir ) ;
113114
114115 console . log ( ) ;
115116 console . log ( ` \u001B[32m✓\u001B[0m Astro build complete` ) ;
116117
117118 return siteDir ;
118119}
119120
121+ /**
122+ * Verify all internal links in the built site using lychee.
123+ * Starts a local server and crawls the site.
124+ */
125+ function verifyBuiltLinks ( siteDir ) {
126+ console . log ( ' → Verifying links in built site...' ) ;
127+
128+ const { spawn } = require ( 'node:child_process' ) ;
129+ const url = new URL ( SITE_URL ) ;
130+ const port = url . port || '4321' ;
131+
132+ // Start local server
133+ const serverProcess = spawn ( 'npx' , [ 'serve' , siteDir , '-l' , port , '--single' ] , {
134+ cwd : PROJECT_ROOT ,
135+ stdio : 'pipe' ,
136+ detached : true ,
137+ } ) ;
138+
139+ // Wait for server to start
140+ execSync ( 'sleep 2' ) ;
141+
142+ try {
143+ execSync ( `lychee 'http://localhost:${ port } /' --no-progress` , {
144+ cwd : PROJECT_ROOT ,
145+ stdio : 'inherit' ,
146+ } ) ;
147+ console . log ( ` \u001B[32m✓\u001B[0m Link verification passed` ) ;
148+ } catch {
149+ console . error ( `\n \u001B[31m✗\u001B[0m Link verification failed - fix broken links before deploying\n` ) ;
150+ process . kill ( - serverProcess . pid ) ;
151+ process . exit ( 1 ) ;
152+ } finally {
153+ try {
154+ process . kill ( - serverProcess . pid ) ;
155+ } catch {
156+ // Server already stopped
157+ }
158+ }
159+ }
160+
120161// =============================================================================
121162// LLM File Generation
122163/**
@@ -330,12 +371,17 @@ async function generatePromptsBundle(downloadsDir) {
330371 */
331372function runAstroBuild ( ) {
332373 console . log ( ' → Running astro build...' ) ;
374+ // Extract base path from SITE_URL for remark plugin
375+ const url = new URL ( SITE_URL ) ;
376+ const basePath = url . pathname . replace ( / \/ $ / , '' ) ; // Strip trailing slash
377+
333378 execSync ( 'npx astro build --root website' , {
334379 cwd : PROJECT_ROOT ,
335380 stdio : 'inherit' ,
336381 env : {
337382 ...process . env ,
338383 SITE_URL ,
384+ BASE_PATH : basePath ,
339385 NODE_OPTIONS : `${ process . env . NODE_OPTIONS || '' } --disable-warning=MODULE_TYPELESS_PACKAGE_JSON` . trim ( ) ,
340386 } ,
341387 } ) ;
0 commit comments