From f049f04a582ed3d2679d6ee874c070b39bc59f83 Mon Sep 17 00:00:00 2001 From: Julian Coy Date: Tue, 23 Jun 2026 15:15:40 -0400 Subject: [PATCH 1/2] Add in design theme --- biome.json | 2 +- lefthook.yml | 2 + .../landing/{design.html => design-dark.html} | 261 +++++++++++---- packages/landing/design-light.html | 311 ++++++++++++++++++ packages/landing/src/components/Nav.tsx | 8 +- packages/landing/vite.config.ts | 3 +- packages/landing/vite/design-system-plugin.ts | 51 +++ 7 files changed, 565 insertions(+), 73 deletions(-) rename packages/landing/{design.html => design-dark.html} (88%) create mode 100644 packages/landing/design-light.html create mode 100644 packages/landing/vite/design-system-plugin.ts diff --git a/biome.json b/biome.json index 30c265f1..8c9d04b5 100644 --- a/biome.json +++ b/biome.json @@ -6,7 +6,7 @@ "useIgnoreFile": true }, "files": { - "includes": ["**", "!**/sst-env.d.ts", "!packages/engine/src/registry/generated"] + "includes": ["**", "!**/sst-env.d.ts", "!packages/engine/src/registry/generated", "!packages/landing/design*.html"] }, "formatter": { "enabled": true, diff --git a/lefthook.yml b/lefthook.yml index 41b0a32a..2aa80cf0 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -15,6 +15,7 @@ pre-commit: - "**/sst-env.d.ts" - "**/generated/**" - "openspec/changes/archive/**" + - "packages/landing/design*.html" run: bun biome check --write --unsafe {staged_files} stage_fixed: true biome-lint: @@ -25,6 +26,7 @@ pre-commit: - "**/sst-env.d.ts" - "**/generated/**" - "openspec/changes/archive/**" + - "packages/landing/design*.html" run: bun biome check --error-on-warnings {staged_files} circleci-pack: priority: 4 diff --git a/packages/landing/design.html b/packages/landing/design-dark.html similarity index 88% rename from packages/landing/design.html rename to packages/landing/design-dark.html index 0da2e071..a54414fa 100644 --- a/packages/landing/design.html +++ b/packages/landing/design-dark.html @@ -1,5 +1,5 @@ - + Agent Facets — Design System @@ -11,17 +11,16 @@ #__bundler_thumbnail svg { width: 100%; height: 100%; object-fit: contain; } #__bundler_placeholder { color: #999; font-size: 14px; } + + - -
- Facets Logo @@ -35,19 +34,19 @@ . slice() rather + // than replace() keeps us clear of $-pattern substitution. + function resourcesFor(id) { + var map = {}; + var list = extResources[id] || []; + for (var k = 0; k < list.length; k++) { + if (blobUrls[list[k].uuid]) map[list[k].id] = blobUrls[list[k].uuid]; + } + return map; + } + for (const id of pageIds) { + let t = pages[id]; + for (const uuid of uuids) t = t.split(uuid).join(blobUrls[uuid]); + t = t.replace(/\s+integrity="[^"]*"/gi, '').replace(/\s+crossorigin="[^"]*"/gi, ''); + // The click interceptor owns every anchor click (not a ): + // a blanket would also redirect form submissions + // and tear down the wrapper. Non-# links navigate the parent to the + // anchor's resolved href; #/… routes forward to the parent's hash only + // when the id is one of this bundle's own pages (author #/… links from + // an in-page hash router are left to the scroll path so they don't yank + // the user to the entry page); plain #frag scrolls in place. + // composedPath + getAttribute('target') handle SVG and shadow-DOM + // anchors, which closest()/IDL .target get wrong. + var headContent = 'window.__resources = ' + JSON.stringify(resourcesFor(id)) + ';' + + (pageIds.length > 1 ? + 'window.__bundler_pages = ' + JSON.stringify(pageIds) + ';' + + 'document.addEventListener("click", function(e){' + + 'if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.defaultPrevented) return;' + + 'var a = null, p = e.composedPath ? e.composedPath() : [e.target];' + + 'for (var j = 0; j < p.length && !a; j++) {' + + 'var n = p[j], tn = n && n.tagName;' + + 'if (tn === "A" || tn === "a" || tn === "AREA") a = n;' + + '}' + + 'if (!a && e.target.closest) a = e.target.closest("a, area");' + + 'if (!a || a.hasAttribute("download")) return;' + + 'var tg = a.getAttribute("target");' + + 'if (tg && tg !== "_self") return;' + + 'var h = a.getAttribute("href") || a.getAttribute("xlink:href");' + + 'if (!h || /^javascript:/i.test(h)) return;' + + 'if (h.charAt(0) !== "#") {' + + 'if (!tg) { var b = document.querySelector("base[target]"); if (b && b.getAttribute("target") !== "_self") return; }' + + 'e.preventDefault();' + + 'if (/^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(h)) parent.location.assign(h);' + + 'return;' + + '}' + + 'e.preventDefault();' + + 'if (h.slice(0, 2) === "#/") {' + + 'var c = h.indexOf(":", 2);' + + 'var pid = c < 0 ? h.slice(2) : h.slice(2, c);' + + 'try { pid = decodeURIComponent(pid); } catch(err) {}' + + 'if (window.__bundler_pages.indexOf(pid) >= 0) { parent.location.hash = h; return; }' + + '}' + + 'var t = h.length > 1 ? document.getElementById(h.slice(1)) : null;' + + 'if (t) t.scrollIntoView({behavior:"smooth"});' + + 'else scrollTo({top:0, behavior:"smooth"});' + + '});' : ''); + // Defuse any script end-tag sequence in the content (resource ids, page + // ids) before wrapping — same escape level as every sibling JSON island. + var headScript = ' diff --git a/packages/landing/design-light.html b/packages/landing/design-light.html new file mode 100644 index 00000000..c1d68ea3 --- /dev/null +++ b/packages/landing/design-light.html @@ -0,0 +1,311 @@ + + + + + Agent Facets — Design System + + + + +
+ + + + + + + + + +
+
Unpacking...
+ + + + + + + + + + diff --git a/packages/landing/src/components/Nav.tsx b/packages/landing/src/components/Nav.tsx index 801f3cac..ece630e2 100644 --- a/packages/landing/src/components/Nav.tsx +++ b/packages/landing/src/components/Nav.tsx @@ -1,5 +1,6 @@ -import { useCallback, useRef, useState } from 'react' +import { useCallback, useMemo, useRef, useState } from 'react' import { useIsMobile } from '../hooks/useIsMobile' +import { useTheme } from '../hooks/useTheme.ts' import { BrandMark } from './BrandMark' import { MobileMenu } from './MobileMenu' import styles from './Nav.module.css' @@ -14,6 +15,7 @@ import { ThemeToggle } from './ThemeToggle' */ export function Nav() { const isMobile = useIsMobile() + const [theme] = useTheme() const [menuOpen, setMenuOpen] = useState(false) const triggerRef = useRef(null) @@ -27,6 +29,8 @@ export function Nav() { setMenuOpen((v) => !v) }, []) + const designLink = useMemo(() => `/design-${theme}`, [theme]) + return ( <>
@@ -45,7 +49,7 @@ export function Nav() { Agent Facets ) : ( - + Agent Facets diff --git a/packages/landing/vite.config.ts b/packages/landing/vite.config.ts index 796eda08..880022c8 100644 --- a/packages/landing/vite.config.ts +++ b/packages/landing/vite.config.ts @@ -4,6 +4,7 @@ import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' import { agentPromptPlugin } from './vite/agent-prompt-plugin' import { brandTokensPlugin } from './vite/brand-tokens-plugin' +import { designSystemPlugin } from './vite/design-system-plugin.ts' // Inject the CLI package's version at build time so the hero eyebrow can // display the shipped CLI version. The CLI is the user-facing artifact; @@ -18,7 +19,7 @@ const cliPkg = JSON.parse(readFileSync(fileURLToPath(cliPkgUrl), 'utf8')) as { v const tokensEmitPath = fileURLToPath(new URL('./src/styles/tokens.generated.css', import.meta.url)) export default defineConfig({ - plugins: [react(), brandTokensPlugin({ emitPath: tokensEmitPath }), agentPromptPlugin()], + plugins: [react(), brandTokensPlugin({ emitPath: tokensEmitPath }), agentPromptPlugin(), designSystemPlugin()], define: { __APP_VERSION__: JSON.stringify(cliPkg.version), }, diff --git a/packages/landing/vite/design-system-plugin.ts b/packages/landing/vite/design-system-plugin.ts new file mode 100644 index 00000000..9a54a7a2 --- /dev/null +++ b/packages/landing/vite/design-system-plugin.ts @@ -0,0 +1,51 @@ +import { readFileSync } from 'node:fs' +import { fileURLToPath } from 'node:url' +import type { Plugin } from 'vite' + +const LIGHT_DESIGN_PATH = fileURLToPath(new URL('../design-light.html', import.meta.url)) +const LIGHT_SERVED_PATH = '/design-light.html' +const LIGHT_ASSET_NAME = 'design-light.html' + +const DARK_DESIGN_PATH = fileURLToPath(new URL('../design-dark.html', import.meta.url)) +const DARK_SERVED_PATH = '/design-dark.html' +const DARK_ASSET_NAME = 'design-dark.html' + +export function designSystemPlugin(): Plugin { + return { + name: 'design-system', + // Emit the .html into the build output so the static-site upload serves + // it at the apex URL the prompt body references. + generateBundle() { + this.emitFile({ + type: 'asset', + fileName: LIGHT_ASSET_NAME, + source: readFileSync(LIGHT_DESIGN_PATH, 'utf8'), + }) + this.emitFile({ + type: 'asset', + fileName: DARK_ASSET_NAME, + source: readFileSync(DARK_DESIGN_PATH, 'utf8'), + }) + }, + // Serve the same file at /design in dev so the hosted URL + // works locally and edits hot-reload through Vite's `?raw` watcher. + configureServer(server) { + server.middlewares.use((req, res, next) => { + const url = req.url?.split('?')[0] + if (url !== LIGHT_SERVED_PATH && url !== DARK_SERVED_PATH) return next() + + if (url === LIGHT_SERVED_PATH) { + res.setHeader('Content-Type', 'text/html; charset=utf-8') + res.end(readFileSync(LIGHT_DESIGN_PATH, 'utf8')) + } + + if (url === DARK_SERVED_PATH) { + res.setHeader('Content-Type', 'text/html; charset=utf-8') + res.end(readFileSync(LIGHT_DESIGN_PATH, 'utf8')) + } + + throw new Error('Uh oh – design system plugin is malfunctioning!') + }) + }, + } +} From 4822cae0ac45f056a023f315c868018a82062f57 Mon Sep 17 00:00:00 2001 From: Julian Coy Date: Tue, 23 Jun 2026 16:48:13 -0400 Subject: [PATCH 2/2] Apply suggestions from code review --- packages/landing/src/components/Nav.tsx | 2 +- packages/landing/vite/design-system-plugin.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/landing/src/components/Nav.tsx b/packages/landing/src/components/Nav.tsx index ece630e2..e0c0e4cb 100644 --- a/packages/landing/src/components/Nav.tsx +++ b/packages/landing/src/components/Nav.tsx @@ -49,7 +49,7 @@ export function Nav() { Agent Facets ) : ( - + Agent Facets diff --git a/packages/landing/vite/design-system-plugin.ts b/packages/landing/vite/design-system-plugin.ts index 9a54a7a2..c4c13037 100644 --- a/packages/landing/vite/design-system-plugin.ts +++ b/packages/landing/vite/design-system-plugin.ts @@ -37,11 +37,13 @@ export function designSystemPlugin(): Plugin { if (url === LIGHT_SERVED_PATH) { res.setHeader('Content-Type', 'text/html; charset=utf-8') res.end(readFileSync(LIGHT_DESIGN_PATH, 'utf8')) + return } if (url === DARK_SERVED_PATH) { res.setHeader('Content-Type', 'text/html; charset=utf-8') - res.end(readFileSync(LIGHT_DESIGN_PATH, 'utf8')) + res.end(readFileSync(DARK_DESIGN_PATH, 'utf8')) + return } throw new Error('Uh oh – design system plugin is malfunctioning!')