@@ -7,12 +7,9 @@ const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
77const srcDir = resolve ( repoRoot , "src" ) ;
88const indexPath = resolve ( srcDir , "index.html" ) ;
99const requiredSections = [
10- "hero" ,
11- "how-it-works" ,
12- "packages" ,
13- "agentcore" ,
14- "quickstart" ,
15- "roadmap"
10+ "top" ,
11+ "why" ,
12+ "install"
1613] ;
1714
1815const index = await readFile ( indexPath , "utf8" ) ;
@@ -41,17 +38,41 @@ const socialPreviewPath = resolve(srcDir, "assets", "repo-social-preview.png");
4138if ( ! existsSync ( socialPreviewPath ) ) {
4239 throw new Error ( "Missing required social preview image: src/assets/repo-social-preview.png" ) ;
4340}
41+ const socialPreviewDimensions = await readPngDimensions ( socialPreviewPath ) ;
42+ if ( socialPreviewDimensions . width !== 1280 || socialPreviewDimensions . height !== 640 ) {
43+ throw new Error (
44+ `Social preview image must be 1280x640; got ${ socialPreviewDimensions . width } x${ socialPreviewDimensions . height } .`
45+ ) ;
46+ }
47+
48+ const orgLogoPath = resolve ( srcDir , "assets" , "org-logo.svg" ) ;
49+ if ( ! existsSync ( orgLogoPath ) ) {
50+ throw new Error ( "Missing required organization logo: src/assets/org-logo.svg" ) ;
51+ }
4452
4553for ( const placeholder of [ "TODO" , "lorem" , "ipsum" , "undefined" ] ) {
4654 if ( index . toLowerCase ( ) . includes ( placeholder . toLowerCase ( ) ) ) {
4755 throw new Error ( `Found placeholder text: ${ placeholder } ` ) ;
4856 }
4957}
5058
59+ for ( const expected of [
60+ "docs" ,
61+ "live-aws-verification.md" ,
62+ "spawn_cloud_agent" ,
63+ "@agent-dispatch/mcp-server" ,
64+ "Live AWS dispatch remains opt-in"
65+ ] ) {
66+ if ( ! index . includes ( expected ) ) {
67+ throw new Error ( `Missing required website copy: ${ expected } ` ) ;
68+ }
69+ }
70+
5171for ( const match of index . matchAll ( / (?: h r e f | s r c ) = " ( [ ^ " ] + ) " / g) ) {
5272 const target = match [ 1 ] ;
5373 if ( target . startsWith ( "http" ) || target . startsWith ( "#" ) || target . startsWith ( "mailto:" ) ) continue ;
54- const localPath = resolve ( dirname ( indexPath ) , target ) ;
74+ const localTarget = target . split ( / [ ? # ] / , 1 ) [ 0 ] ;
75+ const localPath = resolve ( dirname ( indexPath ) , localTarget ) ;
5576 if ( ! existsSync ( localPath ) ) {
5677 throw new Error ( `Broken local asset reference: ${ target } ` ) ;
5778 }
@@ -61,6 +82,12 @@ const css = await readFile(resolve(srcDir, "styles.css"), "utf8");
6182if ( ! css . includes ( "@media" ) || ! css . includes ( ":root" ) ) {
6283 throw new Error ( "CSS must include responsive rules and root design tokens." ) ;
6384}
85+ if ( / l e t t e r - s p a c i n g : \s * - [ 0 - 9 . ] / . test ( css ) ) {
86+ throw new Error ( "CSS must not use negative letter spacing." ) ;
87+ }
88+ if ( / f o n t - s i z e : \s * [ ^ ; ] * v w / . test ( css ) ) {
89+ throw new Error ( "CSS must not scale font size directly with viewport width." ) ;
90+ }
6491
6592const files = [ ] ;
6693async function walk ( dir ) {
@@ -74,3 +101,16 @@ async function walk(dir) {
74101await walk ( srcDir ) ;
75102
76103console . log ( `Validated AgentDispatch website (${ files . length } source files).` ) ;
104+
105+ async function readPngDimensions ( path ) {
106+ const bytes = await readFile ( path ) ;
107+ const signature = bytes . subarray ( 0 , 8 ) . toString ( "hex" ) ;
108+ if ( signature !== "89504e470d0a1a0a" ) {
109+ throw new Error ( `${ path } is not a PNG file` ) ;
110+ }
111+
112+ return {
113+ width : bytes . readUInt32BE ( 16 ) ,
114+ height : bytes . readUInt32BE ( 20 )
115+ } ;
116+ }
0 commit comments