feat(website): new marketing website (Astro) with the agents landing page#5440
Conversation
Static-first Astro marketing site for agenta.ai. Licensed brand fonts (GT Alpina, PP Mondwest) are gitignored and injected at build time from a private Cloudflare R2 bucket by scripts/fetch-fonts.mjs (prebuild/predev), with a system serif/mono fallback so the build never depends on them. Includes the design docs under docs/design/marketing-website/.
A stray GT-Alpina-Regular.woff2 sat at website/ root (outside public/fonts/) and is licensed for use, not redistribution. Removed from the tree; it is injected at build time like the other brand fonts.
Ignores the licensed brand woff2 (GT-Alpina*, PPMondwest*) anywhere under website/ so they are never committed to this public repo; they are injected at build time by scripts/fetch-fonts.mjs.
Each explorer card's Use template link now points at https://cloud.agenta.ai/?template=<key>, where <key> is a key from the app template registry, so the app can create the agent from the chosen template. Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
Add a reduced-motion media guard to global.css so the looping hero/monitor play-button pulse and one-shot accordion reveals neutralize, and hover transitions collapse to instant, when the OS requests reduced motion. Default rendering is unchanged. Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
Port tokens/agenta-dark.css (the canonical warm elevation ladder) into src/styles/tokens-dark.css and wire it into global.css. Add the open-standards marquee keyframes and the nav-pill scroll styles, and port the redesign's responsive rules (templates, open-standards, reliability, open-source) from the design's style block. Keeps the prefers-reduced-motion guard. Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
Add 24 self-hosted SVG marks under public/logos/tools/ (simple-icons, CC0, plus the local GitHub/Slack/Linear/Anthropic/OpenAI marks), normalized to fill=currentColor so components tint them grey. Used by the templates, open standards marquee, and open-source sections. Never hotlink cdn.simpleicons.org. Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
Implement the redesigned agents landing page 1:1 from the updated design comp: new hero copy (open-source [workspace] chip), redesigned Templates section (area tabs + featured two-column panel with a scrollable AGENTS.md viewer, preserving the ?template=<key> deep links), a new scroll-driven How it works section (500vh sticky on desktop, static two-panel fallback under reduced-motion or <=860px), a new Open standards marquee (5 auto-scrolling rows, hover to pause/scroll), a new Reliability 4-column band, a new Open source section with a copy-prompt terminal, refreshed Collaborate/Integrations, the Ship-agents CTA, and the frosted nav-pill scroll behavior. Sections migrated to the warm var(--ag-d-*) tokens. index.astro wires the new section order. Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
HarnessModels, Environments, and Monitor are superseded by the new Open standards and Reliability sections and are no longer imported anywhere. Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
The Vite dep optimizer bakes process.env.NODE_ENV at pre-bundle time. When the dev server inherits NODE_ENV=production, esbuild pulls React's production jsx-dev-runtime (jsxDEV is a no-op), which throws 'jsxDEV is not a function' on hydration and blanks every client:visible island — templates and how-it-works vanish on refresh. Pin the optimizer to development so an ambient NODE_ENV can no longer poison the cache.
Drop the Collaborate section and delete its component. New section order: hero, templates, how it works, open standards, self-host, build-trust, integrations, cta, footer — self-host now precedes the trust section and integrations sits between trust and the cta band.
Remove the Product dropdown and stop every nav link and CTA from opening a new tab (Docs included); the right side is now just Book a demo and Get started. The brand wordmark condenses to the leaf symbol when the nav enters the pill, matching agenta.ai.
Make 'agents' the single highlighted chip (workspace is plain now). Gate the video placeholder off behind SHOW_HERO_VIDEO (no asset yet) by extracting it to HeroVideo.astro, and rebalance the hero's vertical rhythm now that the video is gone (with a tighter mobile rhythm).
…ile hero Give the scrolled nav pill more top offset and add the overflow clip that condenses the brand to the leaf symbol. Fix the footer: below 1200px the 172px side padding dropped the link columns beneath the brand, so tighten the padding and lay the columns out 2-up down to the mobile breakpoint. Trim the hero's vertical padding on mobile to match the removed video.
Split the nav into a fixed-geometry sticky shell + an inner layer that animates via width, paint props, and a translateY only — matching how agenta.ai floats its pill. The nav's layout box no longer changes, so content below no longer shifts when the pill engages. Also rebalance the footer columns (three now) in the responsive rules.
Add seven monochrome marks (pi.dev, OpenCode, Hermes, xAI, Daytona, E2B, your-own-gateway) and wire logos onto every Harness, Providers, and Runtime chip in Open standards and onto the Codex and pi.dev harness options in the template explorer. Capitalize Hermes. Also tighten the Open standards copy to name the harness, model, and runtime.
Delete the "Integrate with everything" section and its component, and gate off the open-source community strip (Star on GitHub / Join the community / View the roadmap) behind a flag, kept in place like the hero video.
Remove the "Now in beta, skills and tools" announcement pill (no longer true) and tighten the highlighted chip so the trailing period reads as part of the sentence.
Replicate the live agenta.ai CTA button CSS (dark and white keycap gradients, inset top-light shadow, 8px radius) and enlarge the decorative Agenta symbol so it reads as a large clipped mark. Remove the footer Product column (those pages are gone), rebalance the remaining three columns, and fix the X icon so both strokes render.
Bundle posthog-js from npm (no CDN, keeps pages self-contained) and init it once from the shared Base layout, mirroring the live agenta.ai reverse-proxy setup (api_host = alef.agenta.ai). Production only via the import.meta.env.PROD gate, honors Do Not Track, captures a pageview per page load. The project key is public by design.
…oy:preview script)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe pull request adds a static Astro marketing website with reusable layouts, interactive sections, pricing, blog and author routes, migrated content and WebP assets, Cloudflare deployment scaffolding, and extensive supporting research. It also adds a separate research document evaluating lightweight self-hosting options. ChangesMarketing website foundation
Website behavior and content
Research and documentation
Estimated code review effort: 5 (Critical) | ~120 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
🟠 Major comments (27)
docs/design/marketing-website/research/blog-migration.md-56-63 (1)
56-63: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winAlign the manifest with the checked-in asset paths and counts.
The manifest documents
.jpgauthor avatars, but the supplied website assets use.webp. It also reports four images fortop-open-source-prompt-management-platforms, while the supplied asset list contains onlyhero.webp. Update the manifest or restore the missing files before relying on the validation claims.Also applies to: 75-75, 107-107
docs/design/marketing-website/research/blog-migration.md-17-24 (1)
17-24: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winReconcile the blog URL count across the migration manifest and inventory.
The migration manifest and the inventory summary disagree, while the inventory table itself contains 37 blog-post rows.
docs/design/marketing-website/research/blog-migration.md#L17-L24: keep the authoritative post/image totals consistent with the final migrated files.docs/design/marketing-website/research/site-inventory.md#L9-L20: update the summary to 37 blog posts and 49 total URLs, or remove the extra row after verification.docs/design/marketing-website/research/site-capture/imprint.md-12-35 (1)
12-35: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winDo not treat this as complete legal content until the missing fields are verified.
The captured page omits or cannot confirm the managing director, registration court/number, and VAT ID. Because
/imprintis the sitewide Contact/legal destination, verify and reproduce the complete legally required content before launch.docs/design/marketing-website/research/site-capture/blog.md-22-64 (1)
22-64: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winReconcile the blog post count before migration.
This inventory says there are 36 posts, while
qa-report.mdrecords 37 rendered cards/posts. Identify the missing slug and make the inventory, content files, and QA report agree so one article is not silently omitted.docs/design/marketing-website/DECISIONS-NEEDED.md-51-54 (1)
51-54: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winDo not publish or commit trial font binaries. The records confirm that trial/demo fonts are deployed and present in the GitButler workspace; leaving replacement as a later launch task risks distributing unlicensed assets.
docs/design/marketing-website/DECISIONS-NEEDED.md#L51-L54: treat removal of the trial deployment as an immediate blocker, not an open launch task.docs/design/marketing-website/TASKS.md#L31-L40: remove trial fonts from the lane and ensure the build only stages approved licensed assets from the configured local/R2 source.website/src/styles/tokens.css#L8-L14: remove the trial-font guidance; retain CSS fallbacks until approved binaries are injected at build time.As per coding guidelines,
website/**/*must not commit proprietary or licensed assets to the public repository.Source: Coding guidelines
docs/design/marketing-website/STATUS.md-7-37 (1)
7-37: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winReconcile the planning records with the implemented Workers site. These files simultaneously describe a completed Cloudflare Workers deployment and an unresolved Vercel-vs-Cloudflare proposal, while retaining a completed Framer import as blocked work.
docs/design/marketing-website/STATUS.md#L7-L37: replace the proposal/Vercel recommendation and decision-pending next steps with the actual implementation and remaining launch blockers.docs/design/marketing-website/AGENTS.md#L121-L133: remove or mark resolved the Astro, deploy-topology, and Gentlet questions.docs/design/marketing-website/TASKS.md#L57-L59: remove the superseded re-import todo or move it to a clearly historical record.As per coding guidelines, planning records must capture decisions and open questions, and
STATUS.mdmust remain the plain-language status.Sources: Coding guidelines, Learnings
website/src/components/CtaBand.astro-7-8 (1)
7-8: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse the CTA props from
Site.astro.CtaBand.astroignoresAstro.props, so thectaoverride passed fromSite.astro(for example on/pricing) never updates the headline, copy, or links. Wire the component to the provided props instead of hardcoding the landing CTA.docs/design/marketing-website/build-notes.md-898-904 (1)
898-904: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse a redirect here, not a rewrite
docs/design/marketing-website/build-notes.md#L898-L904docs/design/marketing-website/deploy-runbook.md#L175-L189A Cloudflare Transform Rule rewrites the request internally; it does not make
/authors/foo/the browser-visible canonical URL. If the slash variant must be canonical, use a 301/308 redirect for/authors/:slug→/authors/:slug/.website/src/components/NavBar.astro-61-68 (1)
61-68: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy liftHardcoded hex colors instead of design tokens across the ported
.astrocomponents. Every reviewed.astrofile mixes literal hex values (#F7F6F4,#100F11,#0B0A0C,#B9B8B6,#15151A,#100F12) with token references (var(--ink-900),var(--yellow-400)) in the same inlinestylestrings — one root cause: the 1:1 design port didn't tokenize every color it introduced.
website/src/components/NavBar.astro#L61-L68: replacebackground:#100F11`` andstroke="#F7F6F4`"` with equivalent tokens (add new ones to `tokens-dark.css` if none exist yet for surface/ink colors).website/src/components/InlineCta.astro#L16-L18: replace the#15151A/#100F12gradient stops andcolor:#F7F6F4`` with tokens.website/src/components/OpenSource.astro#L67-L107: replacecolor:#F7F6F4and `background:`#0B0A0Cwith tokens.website/src/components/OpenStandards.astro#L122-L128: replacebackground-color:#B9B8B6(logo tint) and `color:`#F7F6F4with tokens.website/src/components/PostCard.astro#L63-L100: replace the repeatedcolor:#F7F6F4`` with a token.As per coding guidelines,
website/src/**/*.{astro,css,scss}: "Use the ported design tokens fromsrc/styles/and never invent hexadecimal color values."Source: Coding guidelines
website/src/components/OpenSource.astro-97-103 (1)
97-103: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winSelf-hosting docs link uses
docs.agenta.ai, contradicting the documented convention.
NavBar.astroexplicitly documents that docs links must usehttps://agenta.ai/docsand not thedocs.agenta.aisubdomain, and its own Docs nav link follows that rule. This "Self-hosting docs" CTA usesdocs.agenta.ai/self-host/quick-startinstead, breaking that contract.🔗 Proposed fix
- href="https://docs.agenta.ai/self-host/quick-start" + href="https://agenta.ai/docs/self-host/quick-start"website/src/components/Reliability.astro-44-222 (1)
44-222: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy liftRepeated hardcoded hex colors across components instead of design tokens. Four files invent literal hex values (
#1B1A1E,#242424,#F2F25C/#E7E712,#2A292E,#F7F6F4,#FFFFFF,#fff,#B9B8B6) rather than referencing the ported tokens insrc/styles/.#F7F6F4alone repeats across three files, which strongly suggests it should be a token (e.g. a "text on dark, primary" color) rather than copy-pasted literals in every component.
website/src/components/Reliability.astro#L44-L222: replace#1B1A1E,#242424,#F2F25C/#E7E712,#2A292E, and every#F7F6F4occurrence with the corresponding token(s).website/src/components/SectionTitle.astro#L32-L36: replace the dark-branch#FFFFFFwith a token, matching the light branch'svar(--text-heading)pattern.website/src/components/SiteNav.astro#L46-L56: replace#fffand#F7F6F4with tokens.website/src/components/TemplateExplorer.tsx#L17-L17: replaceLOGO_GREY = "#B9B8B6"(and the other hex literals used elsewhere in this file, e.g.#F7F6F4) with the matching token(s), importing/referencing the same CSS custom properties used by the.astrocomponents.As per coding guidelines,
website/src/**/*.{astro,css,scss}: Use the ported design tokens from src/styles/ and never invent hexadecimal color values.Source: Coding guidelines
website/src/components/TemplateExplorer.tsx-192-220 (1)
192-220: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winArea tabs and harness switch aren't keyboard-accessible.
Both the template area tabs and the harness selector are plain
<span onClick>elements — notabIndex, noonKeyDown/Enter-Space handling, norole/aria-selected. Keyboard-only and screen-reader users cannot switch templates or harnesses at all; mouse is the only way to interact with this island's core feature.Recommend switching to
<button type="button">(native focusability + Enter/Space activation) withrole="tab"/aria-selected(oraria-pressedfor the harness switch) on the active item.♿ Sketch of the fix (area tabs)
- {TEMPLATES.map((t, i) => ( - <span - key={t.key} - onClick={() => { - setSel(i); - setHarness(null); - }} + {TEMPLATES.map((t, i) => ( + <button + key={t.key} + type="button" + role="tab" + aria-selected={i === sel} + onClick={() => { + setSel(i); + setHarness(null); + }} style={{ + border: "none", + font: "inherit", display: "inline-flex", ... }} > {t.area} - </span> + </button> ))}Also applies to: 339-366
website/.env.example-8-11 (1)
8-11: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
PUBLIC_POSTHOG_KEYis not used here
website/.env.examplesays an empty key omits the PostHog snippet, butwebsite/src/components/Analytics.astrostill hardcodes the project key and only gates onimport.meta.env.PROD/DNT. Production forks or previews will still send events to Agenta’s PostHog project even when this env var is unset. Wire the component toimport.meta.env.PUBLIC_POSTHOG_KEYor remove this env var from the example.website/src/layouts/Base.astro-5-8 (1)
5-8: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winImplement the forwarded OG props and head slot
Site.astropassesogType,ogImage, and aheadslot, butBase.astroignores all three. Add the matching props, renderog:type/og:imagein<head>, and include<slot name="head" />so page-specific head content isn’t dropped.website/public/_headers-4-15 (1)
4-15: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick winRemove the inherited
Cache-Controlbefore the asset-specific rules.
/_astro/*,/fonts/*,/og/*,/icons/*,/logos/*,/blog/*, and/authors/*also match/*, so they inherit the page TTL unlessCache-Controlis cleared first. Add! Cache-Controlin each specialized block before setting the longer cache policy.website/src/content/posts/the-ultimate-guide-for-chunking-strategies.mdx-31-47 (1)
31-47: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winBroken import statements in the lead code sample.
Several imports are missing whitespace and won't parse:
from chunking_evaluation.chunkingimport (,# Additional Dependenciesimport tiktoken,from chromadb.utilsimport embedding_functions,from chunking_evaluation.utilsimport openai_token_count. Anyone copy-pasting this first snippet gets an immediateSyntaxError.🐛 Proposed fix
-from chunking_evaluation.chunkingimport ( +from chunking_evaluation.chunking import ( ClusterSemanticChunker, LLMSemanticChunker, FixedTokenChunker, RecursiveTokenChunker, KamradtModifiedChunker ) -# Additional Dependenciesimport tiktoken -from chromadb.utilsimport embedding_functions -from chunking_evaluation.utilsimport openai_token_count +# Additional Dependencies +import tiktoken +from chromadb.utils import embedding_functions +from chunking_evaluation.utils import openai_token_count import oswebsite/src/content/posts/the-guide-to-structured-outputs-and-function-calling-with-llms.mdx-139-157 (1)
139-157: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winFix the OpenAI JSON-mode parameter.
response_format="json"is not a valid Chat Completions value; useresponse_format={"type": "json_object"}instead, or the snippet will fail when copied.website/src/pages/blog/[slug].astro-87-120 (1)
87-120: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy liftRaw hex/rgba colors instead of design tokens, across every page in this batch.
As per coding guidelines,
website/src/**/*.{astro,css,scss}must "Use the ported design tokens fromsrc/styles/and never invent hexadecimal color values." All five pages hardcode#0E0D0F,#F7F6F4,#0A0A0B,#100F11, and variousrgba(255,255,255,…)literals directly in inlinestylestrings — yet the same files already referencevar(--yellow-400),var(--ink-900), andvar(--grad-btn-primary)for other properties, proving the token set exists and is simply not applied consistently.
website/src/pages/blog/[slug].astro#L87-L120: replace#0E0D0F/#F7F6F4/hardcoded rgba border colors in the article header with the matching CSS variables fromsrc/styles/tokens*.css.website/src/pages/authors/[slug].astro#L37-L73: replace the hero section's#0E0D0F/#F7F6F4literals with tokens.website/src/pages/authors/index.astro#L22-L38: replace the header section's#0E0D0F/#F7F6F4literals with tokens.website/src/pages/blog/index.astro#L33-L55: replace the header section's#0E0D0F/#F7F6F4literals with tokens.website/src/pages/contact.astro#L27-L48: replace the hero's#0E0D0F/#100F11/#F7F6F4literals with tokens; the demo button at L76 already shows the correct token-based pattern to follow.Source: Coding guidelines
website/scripts/optimize-images.mjs-111-141 (1)
111-141: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick winConversion proceeds even when WebP output is larger than the original.
There's no check comparing
newSizetooriginalSizebefore deleting the source (line 129) and recording the result.image-manifest.jsonshows this isn't hypothetical: numerous images (e.g.the-ultimate-guide-for-chunking-strategies/img-17.pngat -277.8%,img-18.pngat -165.5%,top-10-techniques-to-improve-rag-applications/img-9.pngat -167.7%) ended up substantially larger as WebP, and are now shipped that way to every visitor. Skip the conversion (keep the original) whenevernewSize >= originalSize.🐛 Proposed fix
const newSize = statSync(webpPath).size; - afterBytes += newSize; - - unlinkSync(src); - - const saving = originalSize - newSize; - const savingPct = ((saving / originalSize) * 100).toFixed(1); - const relPath = src.replace(PUBLIC + "/", ""); - results.push({ - file: "/" + relPath, - originalSize, - newSize, - savingPct, - originalWidth: meta.width, - }); + if (newSize >= originalSize) { + unlinkSync(webpPath); + afterBytes += originalSize; + console.log(` = kept original (webp was larger): ${src}`); + } else { + afterBytes += newSize; + unlinkSync(src); + const saving = originalSize - newSize; + const savingPct = ((saving / originalSize) * 100).toFixed(1); + const relPath = src.replace(PUBLIC + "/", ""); + results.push({ + file: "/" + relPath, + originalSize, + newSize, + savingPct, + originalWidth: meta.width, + }); + }website/src/pages/imprint.astro-18-33 (1)
18-33: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winUse the existing design tokens instead of hard-coded colors.
This page introduces numerous hexadecimal and
rgba(...)values directly in inline styles, bypassing the token system and making the page inconsistent with future theme changes. As per coding guidelines,website/src/**/*.{astro,css,scss}must use the ported design tokens and never invent hexadecimal color values.Also applies to: 42-58, 78-118
Source: Coding guidelines
website/src/pages/index.astro-2-11 (1)
2-11: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winReuse the shared site chrome on the homepage.
The homepage wires its own
SiteNav,SiteFooter, and wrapper instead of usingSite.astro, which already renders the shared navigation/footer and owns the page frame. This will let global chrome fixes diverge between the homepage and other routes. As per coding guidelines, page routes must reuseSite.astroand the sharedNavBar,Footer, andCtaBandcomponents rather than reimplementing navigation or footers per page.Also applies to: 14-29
Source: Coding guidelines
website/src/pages/imprint.astro-4-8 (1)
4-8: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winUpdate the imprint before shipping. The page still references § 5 TMG; switch it to § 5 DDG, and add the missing managing director, register entry, and VAT ID fields if applicable.
website/src/content/posts/cicd-for-llm-prompts.mdx-122-134 (1)
122-134: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd the webhook relay step
repository_dispatchcan’t receive Agenta’s webhook directly; something authenticated has to accept the POST and call GitHub’s dispatch API. Add that relay/GitHub App step before this example, otherwise the flow won’t trigger.website/src/content/posts/cicd-for-llm-prompts.mdx-142-148 (1)
142-148: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winPass dispatch payloads through env before using them in
run.github.event.client_payload.variant_id,version_id, andapp_slugare expanded into the shell here, so a malicious dispatch payload can inject commands or write outsideprompts/. Use intermediate env vars, validate the slug, and failcurlon HTTP errors.website/public/blog/prompt-management-for-non-engineers/hero.webp-1-1 (1)
1-1: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy liftMove the migrated WebP assets out of Git. These large binary files are committed under
website/public, contrary to the website asset-storage rule. Store them in generated deployment output or R2, then update the corresponding content and MDX references.
website/public/blog/prompt-management-for-non-engineers/hero.webp#L1-L1: externalize the hero/OG asset and update its post reference.website/public/blog/prompt-playground/hero.webp#L1-L1: externalize the hero asset and update its post reference.website/public/blog/prompt-versioning-guide/hero.webp#L1-L1: externalize the hero asset and update its post reference.website/public/blog/soc2-type2/hero.webp#L1-L1: externalize the hero asset and update its post reference.website/public/blog/structured-outputs-playground/hero.webp#L1-L1: externalize the hero asset and update its post reference.website/public/blog/top-6-techniques-to-manage-context-length-in-llms/hero.webp#L1-L1: externalize the hero asset and update its post reference.website/public/blog/top-llm-gateways/hero.webp#L1-L1: externalize the hero asset and update its post reference.website/public/blog/top-llm-gateways/img-1.webp#L1-L1: externalize the inline asset and update its MDX reference.website/public/blog/top-llm-gateways/img-2.webp#L1-L1: externalize the inline asset and update its MDX reference.website/public/blog/top-llm-gateways/img-3.webp#L1-L1: externalize the inline asset and update its MDX reference.website/public/blog/top-llm-gateways/img-4.webp#L1-L1: externalize the inline asset and update its MDX reference.As per coding guidelines,
website/**/*must not commit proprietary, licensed, or large binary assets; store them in deployed output or reference R2 URLs instead.Source: Coding guidelines
website/public/blog/the-ai-engineer-s-guide-to-llm-observability-with-opentelemetry/hero.webp-1-66 (1)
1-66: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy liftKeep migrated binary assets out of
website/public.These large WebP blobs are checked into the public repository. Move them to deployed output or R2, updating the consuming MDX URLs, or verify a documented exception for size and licensing.
website/public/blog/the-ai-engineer-s-guide-to-llm-observability-with-opentelemetry/hero.webp#L1-L66: move the hero/OG asset or document an approved exception.website/public/blog/the-ai-engineer-s-guide-to-llm-observability-with-opentelemetry/img-1.webp#L1-L85: move the article image or document an approved exception.website/public/blog/the-ai-engineer-s-guide-to-llm-observability-with-opentelemetry/img-2.webp#L1-L84: move the article image or document an approved exception.website/public/blog/the-definitive-guide-to-prompt-management-systems/hero.webp#L1-L213: move the hero/OG asset or document an approved exception.website/public/blog/the-guide-to-structured-outputs-and-function-calling-with-llms/hero.webp#L1-L227: move the hero/OG asset or document an approved exception.website/public/blog/top-llm-gateways/img-5.webp#L1-L223: move the article image or document an approved exception.website/public/blog/top-llm-observability-platforms/hero.webp#L1-L94: move the hero/OG asset or document an approved exception.website/public/blog/top-llm-observability-platforms/img-1.webp#L1-L291: move the article image or document an approved exception.website/public/blog/top-llm-observability-platforms/img-2.webp#L1-L474: move the article image or document an approved exception.website/public/blog/top-llm-observability-platforms/img-3.webp#L1-L154: move the article image or document an approved exception.website/public/blog/top-llm-observability-platforms/img-4.webp#L1-L199: move the article image or document an approved exception.As per coding guidelines,
website/**/*must not commit proprietary, licensed, or large binary assets to the public repository; store them in deployed output or reference them from R2 URLs instead.website/public/blog/the-guide-to-structured-outputs-and-function-calling-with-llms/img-1.webp-1-1 (1)
1-1: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy liftExternalize the migrated image payloads.
All 11 files are large binary assets committed under
website/public/, violating the website asset policy. Move them to R2 or deployment-only output and preserve/update every corresponding content URL.
website/public/blog/the-guide-to-structured-outputs-and-function-calling-with-llms/img-1.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-guide-to-structured-outputs-and-function-calling-with-llms/img-2.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/hero.webp#L1-L1: externalize the hero image and preserve its hero/OG URLs.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-1.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-10.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-11.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-12.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-13.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-14.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-15.webp#L1-L1: externalize the WebP and preserve its article URL.website/public/blog/the-ultimate-guide-for-chunking-strategies/img-16.webp#L1-L1: externalize the WebP and preserve its article URL.As per coding guidelines: “Do not commit proprietary, licensed, or large binary assets to the public repository; store them in deployed output or reference them from R2 URLs instead.”
Source: Coding guidelines
🟡 Minor comments (40)
website/src/pages/404.astro-25-25 (1)
25-25: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse the shared design tokens for these colors.
#0E0D0Fand#F7F6F4are hard-coded hexadecimal values. Replace them with the corresponding variables fromwebsite/src/styles/tokens*.css.As per coding guidelines,
website/src/**/*.{astro,css,scss}must use the ported design tokens fromsrc/styles/and never invent hexadecimal color values.Also applies to: 36-36
Source: Coding guidelines
docs/design/marketing-website/research/competitive-gumloop.md-43-59 (1)
43-59: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd language identifiers to the fenced schema examples.
Use
text,typescript, or another appropriate language after each opening fence so the documentation passes MD040 and renders consistently.Also applies to: 74-93, 118-137, 182-206, 223-239, 256-286, 297-311, 324-337
Source: Linters/SAST tools
docs/design/marketing-website/research/site-capture/launch-week-1.md-9-35 (1)
9-35: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd the archive year to every launch-week date.
These dates correspond to April 14–18, 2025; adding the year prevents the archive from being interpreted as a 2026 event and keeps it consistent with the migrated post metadata.
docs/design/marketing-website/research/site-capture/launch-week-2.md-10-53 (1)
10-53: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winCorrect the launch-week calendar and Day 2 destination.
The weekday sequence should be checked against the intended year: if this is the 2025 launch week reflected by the migrated posts, the dates are Monday, November 10 through Friday, November 14, 2025—not November 10, 12, 13, 14, and 15. Also change Day 2’s link from
launch-week-2-day-1tolaunch-week-2-day-2-online-evaluation.docs/design/marketing-website/research/current-live-site.md-16-16 (1)
16-16: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winQualify the author-page finding.
This absolute statement conflicts with
live-url-link-map.mdand the author capture files, which document/authors/<slug>/pages. State that author pages were not found by the Jina/WebFetch method, or update the finding to avoid misleading implementers.docs/design/marketing-website/research/current-live-site.md-45-46 (1)
45-46: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winCorrect the Community link inventory.
The documented GitHub and Slack destinations differ from the current
website/src/components/NavBar.astroandlive-url-link-map.md: the nav GitHub link targets Discussions and uses the newer Slack invite token. Reconcile this capture before using it as the navigation source of truth.docs/design/marketing-website/research/live-url-link-map.md-241-287 (1)
241-287: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winMark resolved deltas or refresh this table.
The current-build comparison is stale relative to the supplied
NavBar.astroandFooter.astro: real Resources/Community links, docs destinations, DPA, Trust Center, YouTube, Slack, and/authorsroutes are already present. Leaving these rows marked as outstanding will cause duplicate or incorrect implementation work.website/src/components/BillingToggle.tsx-59-92 (1)
59-92: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRoute component colors through the shared token layer. These inline declarations duplicate palette values and bypass the newly ported theme tokens, so later design-token changes can leave these controls visually inconsistent.
website/src/components/BillingToggle.tsx#L59-L92: replace direct hex/RGBA theme colors with the corresponding dark-theme token variables.website/src/components/Badge.astro#L8-L14: replace inline palette values with semantic/shared token references.website/src/components/Button.astro#L16-L23: replace the direct white value and component palette values with shared tokens.As per coding guidelines,
website/src/**/*.{astro,tsx,jsx}must use ported design tokens and never invent hexadecimal color values.Source: Coding guidelines
docs/design/marketing-website/message-to-design-agent.md-24-27 (1)
24-27: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUpdate the legal-route handoff to the current docs redirects.
This still instructs the design agent that these routes go to Termly, while the recorded final decision redirects both to the Agenta docs security pages. The contradiction can reintroduce the retired Termly routing.
Also applies to: 61-63
docs/design/marketing-website/plan.md-38-65 (1)
38-65: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRemove or mark the Vercel recommendation as superseded.
This section still recommends Vercel, contradicting the locked Cloudflare Workers decision at Lines 135-140. Update it to the final architecture so the plan has one actionable hosting direction.
website/src/components/CopyPromptButton.tsx-19-24 (1)
19-24: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winShow “Copied” only after
writeText()resolveswebsite/src/components/CopyPromptButton.tsx
onCopysets the success state before the clipboard promise settles, so the button can report success even when copying fails or the API is unavailable. Make it async and flip the label only on success.website/src/components/SiteNav.astro-9-15 (1)
9-15: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winPlaceholder dropdown links jump the page to top on click.
Resources/Communityusehref="#"purely to show a chevron; there's no dropdown menu or click handler, so clicking either link scrolls the page to the top — a jarring result for what visually reads as a dropdown trigger. Since these are already flagged as placeholders in the comment above, at minimum prevent the default jump (e.g.href="javascript:void(0)"or a no-op click handler) until the real dropdown ships.website/src/components/SiteFooter.astro-57-57 (1)
57-57: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winCopyright end year (2060) looks like a typo.
Copyright © 2020 – 2060— 2060 is 34 years in the future from today; this reads like a2026→2060transposition. Worth either correcting to the current year or computing it dynamically (new Date().getFullYear()) so it doesn't go stale again.🐛 Suggested fix
-const copyright = "Copyright © 2020 – 2060 Agentatech UG"; +const copyright = `Copyright © 2020 – ${new Date().getFullYear()} Agentatech UG`;website/src/components/SiteFooter.astro-19-19 (1)
19-19: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winSlack link points to the generic signup page, not Agenta's workspace.
https://join.slack.com/is Slack's generic marketing/signup URL, not an invite link into any specific workspace. Visitors clicking this in the footer won't land anywhere related to Agenta.🔗 Suggested fix
- { platform: "slack", url: "https://join.slack.com/", icon: "/icons/social-4.svg" }, + { platform: "slack", url: "<actual Agenta Slack invite URL>", icon: "/icons/social-4.svg" },website/AGENTS.md-66-67 (1)
66-67: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAlign the shared chrome guidance
website/AGENTS.mdstill namesNavBar/Footer, butwebsite/src/layouts/Site.astrouses that pair whilewebsite/src/pages/index.astrousesSiteNav/SiteFooter. Pick one canonical stack, or document the split so the two implementations don’t drift.Source: Coding guidelines
website/src/layouts/Site.astro-54-57 (1)
54-57: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse the existing dark background design token.
Replace
background:#0A0A0B`` with the correspondingsrc/styles/token instead of embedding a hexadecimal value.As per coding guidelines,
website/src/**/*.{astro,css,scss}must “Use the ported design tokens fromsrc/styles/and never invent hexadecimal color values.”Source: Coding guidelines
website/src/content/posts/the-guide-to-structured-outputs-and-function-calling-with-llms.mdx-442-444 (1)
442-444: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRaw HTML tags leaking into rendered text.
<a href="...">and<strong>tags are wrapped inside inline code spans (e.g.`<a href="..."><strong>inspect</strong></a>`module...), so they'll render as literal tag text rather than a working link or bold text. This looks like a content-migration artifact.website/src/content/posts/top-llm-observability-platforms.mdx-65-65 (1)
65-65: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHeading typo changes the meaning: "Automate valuation" → "Automate Evaluation".
The section is about running online evaluations, not valuation.
website/src/content/posts/top-6-techniques-to-manage-context-length-in-llms.mdx-69-72 (1)
69-72: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMulti-line code wrapped in inline backticks instead of a fenced code block.
This snippet is inside a single backtick span spanning multiple lines, which most Markdown renderers won't treat as a code block — expect broken formatting (literal
\nor run-on text) in the rendered post.🐛 Proposed fix
-1. **Determine the model’s maximum input token limit** `# User-defined: Reserve space for output -context_window = 128000 # GPT-4o total -max_output_tokens = 4000 # Your desired response length -max_input_tokens = context_window - max_output_tokens # 124K` +1. **Determine the model’s maximum input token limit** + + ```python + # User-defined: Reserve space for output + context_window = 128000 # GPT-4o total + max_output_tokens = 4000 # Your desired response length + max_input_tokens = context_window - max_output_tokens # 124K + ```website/src/content/posts/top-open-source-prompt-management-platforms.mdx-110-124 (1)
110-124: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse
labelfor the production prompt pointerLangfuse treats
versionas a numeric version, whileproductionis a label. Change this tolabel="production"(or omit the argument, since production is the default).website/src/pages/contact.astro-143-150 (1)
143-150: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winSlack CTA should use the workspace invite URL.
https://join.slack.com/is the generic Slack landing page, so this button doesn’t take users directly to the Agenta community. Swap in the actual invite link used elsewhere in the site.website/src/content/posts/what-we-learned-building-a-prompt-management-system.mdx-15-15 (1)
15-15: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winFix the heading grammar.
“Why Prompt Management Matter” should be “Why Prompt Management Matters.”
website/src/content/posts/what-we-learned-building-a-prompt-management-system.mdx-25-29 (1)
25-29: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRemove the duplicated and misspelled paragraph.
Line 25 repeats the corrected explanation on Line 27 and contains “ofter” plus incorrect phrasing. Line 29 also says “Real-word example”; use “Real-world example.”
Source: Linters/SAST tools
website/src/content/posts/what-we-learned-building-a-prompt-management-system.mdx-212-212 (1)
212-212: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd spaces between adjacent Markdown spans.
The CTA currently concatenates words such as
?Agenta,deployment.Book, anddemoandin the rendered output.website/src/content/posts/what-we-learned-building-a-prompt-management-system.mdx-51-51 (1)
51-51: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRemove or complete the empty fourth list item in both migrated articles. Each page currently renders a dangling
4.with no content.
website/src/content/posts/what-we-learned-building-a-prompt-management-system.mdx#L51-L51: add the missing step or remove the empty marker.website/src/content/posts/building-the-data-flywheel-how-to-use-production-data-to-improve-your-llm-application.mdx#L51-L51: add the missing step or remove the empty marker.website/src/content/posts/agenta-achieves-soc2-type-i-certification.mdx-3-4 (1)
3-4: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse consistent SOC 2 terminology.
Standardize the article on
SOC 2 Type Irather than mixingSOC2,SOC 2, andType 1.Also applies to: 15-15, 23-23, 50-50
Source: Linters/SAST tools
website/src/content/posts/building-the-data-flywheel-how-to-use-production-data-to-improve-your-llm-application.mdx-107-107 (1)
107-107: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winFix the malformed references paragraph.
The first URL contains an extra
], the author name is misspelled as “Jason Lui,” and missing spaces concatenate the links and following sentences.website/src/content/posts/what-we-learned-building-a-prompt-management-system.mdx-136-136 (1)
136-136: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRemove the unmatched bold delimiter.
The link text is already bold; the trailing
**before the colon is stray Markdown and can affect rendering.Proposed fix
-- [**Playground Integration**](https://docs.agenta.ai/prompt-management/using-the-playground)**: +- [**Playground Integration**](https://docs.agenta.ai/prompt-management/using-the-playground):website/src/content/posts/humanloop-sunsetting-migration-and-alternative.mdx-72-72 (1)
72-72: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRemove the literal outer brackets from the CTAs.
The outer
[and]render as visible text around each link rather than creating buttons.Proposed fix
-[[**Book Free Migration Call**](https://cal.com/mahmoud-mabrouk-ogzgey/demo)] [[**Try Agenta Now**](https://cloud.agenta.ai)] +[**Book Free Migration Call**](https://cal.com/mahmoud-mabrouk-ogzgey/demo) · [**Try Agenta Now**](https://cloud.agenta.ai)website/src/content/posts/introducing-prompt-registry.mdx-46-46 (1)
46-46: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd descriptive
titleattributes to all embedded YouTube iframes.The same omission appears in all six embeds; without a title, assistive technology cannot identify the video content.
website/src/content/posts/introducing-prompt-registry.mdx#L46-L46: add a title describing the Prompt and Configuration Registry demo.website/src/content/posts/july-2025-product-updates.mdx#L21-L21: add a title describing the tool-support video.website/src/content/posts/july-2025-product-updates.mdx#L35-L35: add a title describing the image-support video.website/src/content/posts/launch-week-2-day-1.mdx#L15-L15: add a title describing the evaluation-dashboard video.website/src/content/posts/launch-week-2-day-2-online-evaluation.mdx#L25-L25: add a title describing the online-evaluation video.website/src/content/posts/launch-week-2-day-3-evaluation-sdk.mdx#L15-L15: add a title describing the Evaluation SDK video.website/src/content/posts/launch-week-2-day-1.mdx-49-49 (1)
49-49: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd or correct the missing evaluator-configuration image asset.
The post references
/blog/launch-week-2-day-1/img-2.gif, but the supplied asset list contains onlyhero.webpandimg-1.webpfor this post. Add the GIF or update the MDX to an existing path.website/src/content/posts/launch-week-2-day-2-online-evaluation.mdx-46-46 (1)
46-46: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winPoint the “docs” CTA to documentation.
The copy says “Check out our docs,” but the target is
https://cloud.agenta.ai, the product application. Link to the online-evaluation documentation or change the copy to a Cloud CTA.website/src/content/posts/launch-week-2-day-5-jinja2-prompt-templates.mdx-75-75 (1)
75-75: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winInsert the missing space after the Product Hunt link.
The rendered text currently joins
Product Hunt)andnow, producing...Product Hunt)now....website/src/content/posts/llm-as-a-judge-guide-to-llm-evaluation-best-practices.mdx-25-25 (1)
25-25: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRun an editorial pass before publishing this post.
Several changed paragraphs contain grammar or wording defects, including “it's, to be honest, is,” “taking into consideration,” “Here is the best process … is,” and “designing and LLM.” These should be corrected in the published article.
Also applies to: 37-37, 48-54, 86-86
Source: Linters/SAST tools
website/src/content/posts/product-update-november-2024.mdx-31-31 (1)
31-31: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winRestore the missing CTA links.
These sentences promise documentation, a notebook, and evaluator instructions, but render as plain text. Add the corresponding Markdown links so users can complete the advertised workflows.
Based on learnings, blog posts should remain functionally equivalent to the current CMS pages and preserve actionable CTA destinations.
Also applies to: 43-43, 51-51
Source: Learnings
website/src/content/posts/prompt-playground.mdx-69-69 (1)
69-69: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winUse HTTPS for the LlamaIndex link.
The current
http://llamaindex.ai/link downgrades navigation from the HTTPS site. Replace it with the HTTPS destination.website/src/content/posts/prompt-versioning-guide.mdx-114-114 (1)
114-114: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd semantic structure to both comparison tables.
Use
<caption>,<thead>, andscope="col"headers instead of placing all headers directly in<tbody>. This is needed for screen readers to associate each data cell with its column.Also applies to: 134-134
website/src/content/posts/open-source-llm-observability.mdx-68-74 (1)
68-74: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winImport
osin the runnable example.The snippet calls
os.environbut never importsos, so copying it verbatim raisesNameErrorbefore initialization.Proposed fix
import agenta as ag +import os from opentelemetry.instrumentation.openai import OpenAIInstrumentorwebsite/src/content/posts/prompt-playground.mdx-25-25 (1)
25-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAdd an accessible name to the YouTube iframe.
Without a
title, assistive technologies cannot identify the embedded content. Add a descriptive title and lazy-load the non-critical video.Proposed fix
-<iframe src="https://www.youtube.com/embed/Eo3S52cejUY?iv_load_policy=3&rel=0&modestbranding=1&playsinline=1&autoplay=0&mute=1" ... +<iframe title="Playground 2.0 overview" loading="lazy" src="https://www.youtube.com/embed/Eo3S52cejUY?iv_load_policy=3&rel=0&modestbranding=1&playsinline=1&autoplay=0&mute=1" ...website/src/content/posts/open-source-llm-observability.mdx-80-88 (1)
80-88: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUpdate this snippet to the current OpenAI client API.
openai.ChatCompletion.createis removed in openai-python 1.x; usefrom openai import OpenAIandclient.chat.completions.create(...)instead.
🧹 Nitpick comments (7)
docs/design/marketing-website/research/current-repo-setup.md (1)
170-170: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAlign the hosting recommendation with the selected deployment model.
This still recommends a Cloudflare Pages project, while this PR uses Cloudflare Workers and the project guidance explicitly requires Workers rather than Pages. Update the recommendation or mark it as superseded so future migration work does not select the wrong platform.
Source: Learnings
website/src/components/CtaBand.astro (1)
18-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReplace component color literals with the ported design tokens.
website/src/components/CtaBand.astro#L18-L21: move the button surface/text literals to semantic token references.website/src/components/Footer.astro#L135-L140: use the footer surface and border tokens.website/src/components/Hero.astro#L29-L32: use the heading/text and chip tokens.website/src/components/HeroVideo.astro#L8-L8: use existing dark-surface and border/shadow tokens.As per coding guidelines: “Use the ported design tokens from
src/styles/and never invent hexadecimal color values.”Source: Coding guidelines
website/src/components/OpenStandards.astro (1)
180-212: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winDuplicated marquee chips are not hidden from assistive tech.
The chip list is duplicated (
r.chips.concat(r.chips)) for the seamless scroll loop, but both copies remain real, focusable links. Screen-reader and keyboard users will hit every tool link twice per row with no indication the second set is decorative.♻️ Proposed fix
{r.chips.concat(r.chips).map((c) => - c.href ? ( + c.href ? ( <a href={c.href} target={isExternal(c.href) ? "_blank" : undefined} rel={isExternal(c.href) ? "noopener" : undefined} style={chipStyle(c)} + aria-hidden={idx >= r.chips.length ? "true" : undefined} + tabIndex={idx >= r.chips.length ? -1 : undefined} >(mark the second half of the concatenated array
aria-hidden+tabindex="-1", e.g. by mapping with an index and comparing againstr.chips.length.)website/src/components/SiteNav.astro (1)
119-131: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueUnbounded per-frame rAF polling for the nav-pill state.
This rAF loop runs forever for the life of the page, every frame, purely to compare
scrollYagainst a threshold. It's a legitimate cross-browser-reliability trade-off (per the comment), and the per-tick cost is trivial, so this is optional rather than blocking — but a passivescrolllistener with an internal rAF-throttle (only scheduling a frame when a scroll event actually fires) would get the same reliability without the always-on loop.website/scripts/import-framer.mjs (2)
114-121: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winHardcoded machine-specific scratch path.
/tmp/claude-1000/-home-mahmoud-code-agenta/26f40a6a-8d2e-490f-9048-49f051a3bb87/scratchpadis a session-specific path from a local coding-assistant run, not something that exists on other machines or CI. Use a repo-relative path instead (e.g.path.join(ROOT, ".scratch")), gitignored if needed.
336-362: 🎯 Functional Correctness | 🔵 Trivial | ⚖️ Poor tradeoffNested lists can be mis-parsed.
The top-level
<li>regex here isn't depth-aware, unlikeblockToMd's tag matcher (lines 451-476). If a Framer list item contains a nested<ul>/<ol>, this regex will terminate at the nested list's own</li>, truncating the item and mangling the nested list. Apply the same depth-tracking approach used inblockToMdfor consistency and correctness on any future re-import.website/scripts/optimize-images.mjs (1)
24-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd
sharpas a direct dependency and drop the version-pinned pnpm path hack.website/package.jsondoesn’t declaresharp, so the current.pnpm/sharp@0.34.5/.33.5lookup is brittle and will fail on the next bump. Import it normally once it’s added there.
…match The featured-row side cards rendered a broken image: the thumbnail was a fixed 116px wide but stretched to the full (taller) card height, so a 16:9 hero was cover-cropped into a ~116x251 vertical sliver (aspect 0.46) that showed only a meaningless fragment of the baked-in title art. Root cause: the featured row was lopsided (left card ~896px, right column a narrow fixed 388px), so the side-card image had no room to crop sanely. Fix, matching agenta.ai/blog: - Make the featured row two equal columns (.ag-sec flex:0 0 388px -> flex:1), so the side cards get the same width as the left card. - Size the side-card image proportionally (flex:0 0 116px -> 40%) so, stretched to full card height, it crops near-square (~1.0 aspect) like the live site. The height match is preserved (right1 + gap + right2 == left card height), text no longer clips, and it holds at 1440 and 412.
…flow - Analytics: only initialize PostHog on agenta.ai / www.agenta.ai so preview deploys (team preview + per-PR CI) stop sending events to the real project. - Add /llms.txt endpoint (llms.txt convention) mapping the site for AI crawlers, which robots.txt already allows. - Add the production deploy workflow (16-website-production.yml) + a production wrangler config (wrangler.production.jsonc) that deploys the agenta-website worker on merge to main touching website/**.
Remove QA reports/screenshots, Framer-era research and site captures, competitive analysis, and Cloudflare/deploy investigations from the docs/design/marketing-website/ folder — local-reference material, not future-work knowledge, and unfit for a public repo. Keep only the four files future work needs: a lean AGENTS.md folder guide, plan.md, the redirect-parity live-url-link-map.md, and blog-migration.md (the last two are referenced by the site's own code). Also drop the unrelated docs/design/lightweight-self-hosting/research.md that was swept into this branch. Archived locally outside git before removal; nothing lost.
…lytics gating - CtaBand.astro: consume Astro.props so per-page cta overrides (/pricing, /contact) apply instead of the hardcoded landing copy. - public/_headers: clear inherited Cache-Control (! Cache-Control) on each asset block so /_astro, /fonts, etc. don't ship a comma-joined dual-max-age header. - TemplateExplorer.tsx: area tabs + harness switch are real buttons with role/aria-selected/aria-pressed (keyboard + screen-reader operable). - OpenStandards.astro: duplicated marquee chips marked aria-hidden + tabindex=-1. - CopyPromptButton.tsx: await writeText; flip to Copied only on success. - SiteFooter.astro: dynamic copyright year; real Slack workspace invite (footer). - contact.astro: real Slack workspace invite. - tokens.css: quote font-family fallbacks (stylelint value-keyword-case). - optimize-images.mjs: keep original when WebP is not smaller. - import-framer.mjs: decode & last (no double-unescape), escape backslashes, repo-relative gitignored scratch dir (CodeQL + nitpick). - .gitignore: ignore .scratch/. Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
Review triage — website fixes (commit
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
The key is ingest-only and public by design (gitleaks false-positive at commit time; committed with hooks bypassed). Runtime host guard keeps previews silent.
…noindex, header scoping, dead link
- blog/index.astro: add the missing #blog-grid > a.blog-hidden { display:none }
rule. The Load-more script toggled .blog-hidden but no stylesheet defined it, so
every post showed at once and the button did nothing. Composes with the category
filter (filtered views strip .blog-hidden and reveal all matching posts).
- 15-website-preview.yml + package.json deploy:preview: set PUBLIC_NOINDEX=true so
public workers.dev previews ship a noindex meta + disallow-all robots.txt and never
rank as duplicate content. Production workflow deliberately leaves it unset.
- public/_headers: scope the blog/author image cache rules to their exact segment
depth (/blog/:slug/:file, /authors/:file) so the generated post/author HTML routes
no longer inherit the week-long image TTL and keep the short /* HTML policy.
- top-6-techniques-...mdx: repoint a dead inline link (the target slug 404s on live
agenta.ai too) to the closest migrated post, top-10-techniques-to-improve-rag-applications.
- website/AGENTS.md: document the preview noindex requirement.
Preview
Shareable team preview (Cloudflare Workers, deployed from this branch):
https://agenta-website-preview.mahmoud-637.workers.dev
Open it, click around, and leave feedback on this PR. The preview is the fastest way to review copy, section order, and mobile behavior.
Context
Our marketing site (agenta.ai) lives on Framer today. That keeps the site outside the monorepo, off our review flow, and hard to iterate on with the rest of the product. This PR brings the marketing site into the repo as a standalone Astro package and ships the redesigned dark agents landing page as the new home page.
Nothing here touches
web/(the app) ordocs/(Docusaurus). It is a self-contained package underwebsite/.What's inside
A new
website/Astro package, static-first (output: 'static'), with browser-side React islands for the interactive bits.Pages: landing, pricing, blog (index plus migrated posts), authors, contact, imprint, and a 404. 47 pages build in total.
The redesigned landing sections:
Supporting systems:
src/styles/(never a hand-picked hex; everything comes from the tokens).scripts/fetch-fonts.mjsinjects the woff2 at build time from a local directory or Cloudflare R2. The binaries are gitignored and never enter the repo. They ship only in the deployed artifact. If no source is available the script exits cleanly and the CSS falls back to system serif and mono, so the build never breaks.public/logos/.docs/design/marketing-website/.This branch also adds
website/wrangler.jsoncand adeploy:previewscript, which is how the preview above was built and deployed (Cloudflare Workers Static Assets serving the prebuiltdist/).How to run it
pnpm devrunsfetch-fontsfirst, but that step is optional. Without the licensed fonts on disk it warns, exits 0, and the site falls back to system fonts. Everything else works the same.What to review
This is a marketing page, so the useful feedback is mostly editorial and visual:
Do not merge yet
This PR needs review and must not be merged without Mahmoud.
https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB