diff --git a/docs/.astro/collections/blog.schema.json b/docs/.astro/collections/blog.schema.json
index bbef581c2..bf04f626c 100644
--- a/docs/.astro/collections/blog.schema.json
+++ b/docs/.astro/collections/blog.schema.json
@@ -13,6 +13,34 @@
"date": {
"type": "string"
},
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "author": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "anyOf": [
+ {
+ "type": "string",
+ "format": "date-time"
+ },
+ {
+ "type": "string",
+ "format": "date"
+ },
+ {
+ "type": "integer",
+ "format": "unix-time"
+ }
+ ]
+ },
+ "status": {
+ "type": "string"
+ },
"$schema": {
"type": "string"
}
diff --git a/docs/.astro/collections/docs.schema.json b/docs/.astro/collections/docs.schema.json
index 9a3631335..8564032b5 100644
--- a/docs/.astro/collections/docs.schema.json
+++ b/docs/.astro/collections/docs.schema.json
@@ -13,6 +13,34 @@
"order": {
"type": "number"
},
+ "tags": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "author": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "anyOf": [
+ {
+ "type": "string",
+ "format": "date-time"
+ },
+ {
+ "type": "string",
+ "format": "date"
+ },
+ {
+ "type": "integer",
+ "format": "unix-time"
+ }
+ ]
+ },
+ "status": {
+ "type": "string"
+ },
"$schema": {
"type": "string"
}
diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs
index cdc2b79dd..7f7d76baf 100644
--- a/docs/astro.config.mjs
+++ b/docs/astro.config.mjs
@@ -1,11 +1,13 @@
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
+import sitemap from '@astrojs/sitemap';
import { remarkRewriteLinks } from './src/plugins/remark-rewrite-links.mjs';
import { rehypePagefindAttrs } from './src/plugins/rehype-pagefind-attrs.mjs';
export default defineConfig({
site: 'https://bradygaster.github.io',
base: '/squad/',
+ integrations: [sitemap()],
vite: {
plugins: [tailwindcss()],
},
diff --git a/docs/package-lock.json b/docs/package-lock.json
index cebb2c48f..c26fe6e5f 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -8,6 +8,8 @@
"name": "squad-docs",
"version": "0.0.1",
"dependencies": {
+ "@astrojs/rss": "^4.0.17",
+ "@astrojs/sitemap": "^3.7.1",
"@tailwindcss/vite": "^4.1.0",
"astro": "^5.7.0",
"sharp": "^0.34.5",
@@ -71,6 +73,46 @@
"node": "18.20.8 || ^20.3.0 || >=22.0.0"
}
},
+ "node_modules/@astrojs/rss": {
+ "version": "4.0.17",
+ "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-4.0.17.tgz",
+ "integrity": "sha512-eV+wdMbeVKC9+sPaV0LN8JL1LGo9YAh3GKl4Ou4nzMNLmXM/aswYpSGxVEAuHilgBZ6/++/Pv08ICmuOqX107w==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-xml-parser": "5.4.1",
+ "piccolore": "^0.1.3",
+ "zod": "^4.3.6"
+ }
+ },
+ "node_modules/@astrojs/rss/node_modules/zod": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
+ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@astrojs/sitemap": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.1.tgz",
+ "integrity": "sha512-IzQqdTeskaMX+QDZCzMuJIp8A8C1vgzMBp/NmHNnadepHYNHcxQdGLQZYfkbd2EbRXUfOS+UDIKx8sKg0oWVdw==",
+ "license": "MIT",
+ "dependencies": {
+ "sitemap": "^9.0.0",
+ "stream-replace-string": "^2.0.0",
+ "zod": "^4.3.6"
+ }
+ },
+ "node_modules/@astrojs/sitemap/node_modules/zod": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
+ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
"node_modules/@astrojs/telemetry": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz",
@@ -1898,6 +1940,24 @@
"@types/unist": "*"
}
},
+ "node_modules/@types/node": {
+ "version": "24.12.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz",
+ "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/sax": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
+ "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -2021,6 +2081,12 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "license": "MIT"
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -3263,6 +3329,40 @@
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"license": "MIT"
},
+ "node_modules/fast-xml-builder": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
+ "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "path-expression-matcher": "^1.1.3"
+ }
+ },
+ "node_modules/fast-xml-parser": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz",
+ "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "fast-xml-builder": "^1.0.0",
+ "strnum": "^2.1.2"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
@@ -4993,6 +5093,21 @@
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
+ "node_modules/path-expression-matcher": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz",
+ "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/piccolore": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz",
@@ -5454,6 +5569,25 @@
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
"license": "MIT"
},
+ "node_modules/sitemap": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz",
+ "integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "^24.9.2",
+ "@types/sax": "^1.2.1",
+ "arg": "^5.0.0",
+ "sax": "^1.4.1"
+ },
+ "bin": {
+ "sitemap": "dist/esm/cli.js"
+ },
+ "engines": {
+ "node": ">=20.19.5",
+ "npm": ">=10.8.2"
+ }
+ },
"node_modules/smol-toml": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz",
@@ -5485,6 +5619,12 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/stream-replace-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz",
+ "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==",
+ "license": "MIT"
+ },
"node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
@@ -5531,6 +5671,18 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
+ "node_modules/strnum": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz",
+ "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/svgo": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz",
@@ -5697,6 +5849,12 @@
"integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==",
"license": "MIT"
},
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "license": "MIT"
+ },
"node_modules/unified": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
diff --git a/docs/package.json b/docs/package.json
index c0e858c85..9a4b0ceca 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -13,6 +13,8 @@
"test:e2e": "npx playwright test"
},
"dependencies": {
+ "@astrojs/rss": "^4.0.17",
+ "@astrojs/sitemap": "^3.7.1",
"@tailwindcss/vite": "^4.1.0",
"astro": "^5.7.0",
"sharp": "^0.34.5",
diff --git a/docs/public/robots.txt b/docs/public/robots.txt
new file mode 100644
index 000000000..ae9d9c74b
--- /dev/null
+++ b/docs/public/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+Sitemap: https://squad.dev/sitemap-index.xml
+
diff --git a/docs/src/components/TableOfContents.astro b/docs/src/components/TableOfContents.astro
new file mode 100644
index 000000000..6a2f276aa
--- /dev/null
+++ b/docs/src/components/TableOfContents.astro
@@ -0,0 +1,46 @@
+---
+// Client-side Table of Contents — reads h2/h3 from the article after render
+---
+
+
+
+
diff --git a/docs/src/content/config.ts b/docs/src/content/config.ts
index eb6b9816a..ee1446d31 100644
--- a/docs/src/content/config.ts
+++ b/docs/src/content/config.ts
@@ -7,6 +7,10 @@ const docs = defineCollection({
title: z.string().optional(),
description: z.string().optional(),
order: z.number().optional(),
+ tags: z.array(z.string()).optional(),
+ author: z.string().optional(),
+ updatedAt: z.coerce.date().optional(),
+ status: z.string().optional(),
}),
});
@@ -16,6 +20,10 @@ const blog = defineCollection({
title: z.string().optional(),
description: z.string().optional(),
date: z.coerce.string().optional(),
+ tags: z.array(z.string()).optional(),
+ author: z.string().optional(),
+ updatedAt: z.coerce.date().optional(),
+ status: z.string().optional(),
}),
});
diff --git a/docs/src/layouts/BaseLayout.astro b/docs/src/layouts/BaseLayout.astro
index fe6b5a4b4..c4b052af5 100644
--- a/docs/src/layouts/BaseLayout.astro
+++ b/docs/src/layouts/BaseLayout.astro
@@ -4,6 +4,7 @@ interface Props {
description?: string;
}
+import { ViewTransitions } from 'astro:transitions';
import squadLogo from '../assets/images/squad-logo.png';
const { title, description = 'Squad — Your AI Development Team. Describe what you\'re building. Get a team of specialists that live in your repo.' } = Astro.props;
const fullTitle = `${title} — Squad Docs`;
@@ -29,10 +30,13 @@ const ogImage = Astro.site ? new URL(squadLogo.src, Astro.site).href : squadLogo
{canonicalUrl && }
-
+
+
+
+