Skip to content

feat(website): new marketing website (Astro) with the agents landing page#5440

Merged
mmabrouk merged 47 commits into
mainfrom
marketing-website
Jul 22, 2026
Merged

feat(website): new marketing website (Astro) with the agents landing page#5440
mmabrouk merged 47 commits into
mainfrom
marketing-website

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

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) or docs/ (Docusaurus). It is a self-contained package under website/.

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:

  • Templates gallery with deep-links into Agenta cloud, so a visitor can open a template straight in the product.
  • Sticky-scroll "How it works" that steps through the workflow as you scroll.
  • Open-standards marquees (the tools and standards we speak).
  • Self-host section and a reliability band.
  • Closing CTA.

Supporting systems:

  • A warm dark token system in src/styles/ (never a hand-picked hex; everything comes from the tokens).
  • A zero-shift frosted nav pill (the nav does not reflow or jump when it changes state).
  • PostHog analytics through the existing alef.agenta.ai reverse proxy, public project key only. No secrets in the repo.
  • A font pipeline for the two licensed faces (GT Alpina, PP Mondwest). scripts/fetch-fonts.mjs injects 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.
  • 30+ self-hosted monochrome brand marks under public/logos/.
  • Planning and design docs under docs/design/marketing-website/.

This branch also adds website/wrangler.jsonc and a deploy:preview script, which is how the preview above was built and deployed (Cloudflare Workers Static Assets serving the prebuilt dist/).

How to run it

cd website
pnpm install
pnpm dev        # http://localhost:4321/

pnpm dev runs fetch-fonts first, 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:

  • Copy: headlines, section text, CTA wording.
  • Section order on the landing page: does the story flow.
  • Mobile behavior: nav, the sticky-scroll section, the marquees, and the templates gallery on a narrow screen.

Do not merge yet

This PR needs review and must not be merged without Mahmoud.

https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB

mmabrouk added 21 commits July 21, 2026 11:33
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.
@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jul 22, 2026 2:50pm

Request Review

@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jul 21, 2026
@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@dosubot dosubot Bot added the Frontend label Jul 21, 2026
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The 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.

Changes

Marketing website foundation

Layer / File(s) Summary
Astro package and deployment foundation
website/*, website/src/layouts/*, website/src/styles/*, website/wrangler.jsonc, website/public/_headers, website/public/_redirects
Defines the static Astro site, shared layouts, design tokens, responsive CSS, caching/security headers, redirects, robots behavior, font handling, and Cloudflare Workers configuration.
Deployment and content tooling
website/scripts/*, docs/design/marketing-website/deploy/*, docs/design/marketing-website/deploy-runbook.md
Adds Framer import, image optimization, font retrieval, image manifests, draft GitHub Actions deployment, and deployment runbook procedures.

Website behavior and content

Layer / File(s) Summary
Shared components and interactive landing sections
website/src/components/*, website/src/pages/index.astro
Adds navigation, footer, hero, CTA, reliability, open-source, open-standards, templates, and scroll-driven "How It Works" components, including React islands for interactive behavior.
Content model and routes
website/src/content.config.ts, website/src/content/*, website/src/pages/*, website/src/lib/blog.ts
Adds validated post and author collections, blog helpers, author profiles, blog listing/detail pages, pricing, contact, imprint, and custom 404 routes.
Migrated editorial content and media
website/src/content/posts/*, website/public/authors/*, website/public/blog/*
Adds migrated author data, numerous MDX articles, author images, blog hero images, and in-body WebP assets.
Pricing data and interaction
website/src/data/pricing.json, website/src/components/HostingToggle.tsx, website/src/components/PlanCard.astro, website/src/pages/pricing.astro
Adds cloud and self-hosted plan definitions, comparison rows, FAQs, plan cards, and an accessible hosting-mode toggle that switches visible plan grids.

Research and documentation

Layer / File(s) Summary
Marketing-site research and decisions
docs/design/marketing-website/**/*.md
Documents repository setup, hosting, URL mapping, live-site capture, Framer migration, competitive research, design handoffs, status, tasks, QA, and implementation notes.
Lightweight self-hosting analysis
docs/design/lightweight-self-hosting/research.md
Inventories the self-host stack, identifies resource drivers, compares lite bundles, evaluates SQLite, documents Windows and Cloud Run constraints, and proposes a phased simplification plan.

Estimated code review effort: 5 (Critical) | ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.78% which is insufficient. The required threshold is 60.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the new Astro marketing website and its main landing page.
Description check ✅ Passed The description is clearly aligned with the website migration and landing-page rebuild changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch marketing-website

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread website/scripts/import-framer.mjs Fixed
Comment thread website/scripts/import-framer.mjs Fixed
Comment thread website/scripts/import-framer.mjs Fixed
Comment thread website/scripts/import-framer.mjs Fixed
Comment thread website/scripts/import-framer.mjs Fixed
Comment thread website/scripts/import-framer.mjs Fixed
Comment thread website/scripts/import-framer.mjs Fixed
Comment thread website/scripts/import-framer.mjs Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Align the manifest with the checked-in asset paths and counts.

The manifest documents .jpg author avatars, but the supplied website assets use .webp. It also reports four images for top-open-source-prompt-management-platforms, while the supplied asset list contains only hero.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 win

Reconcile 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 win

Do 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 /imprint is 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 win

Reconcile the blog post count before migration.

This inventory says there are 36 posts, while qa-report.md records 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 win

Do 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 win

Reconcile 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.md must remain the plain-language status.

Sources: Coding guidelines, Learnings

website/src/components/CtaBand.astro-7-8 (1)

7-8: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the CTA props from Site.astro. CtaBand.astro ignores Astro.props, so the cta override passed from Site.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 win

Use a redirect here, not a rewrite

  • docs/design/marketing-website/build-notes.md#L898-L904
  • docs/design/marketing-website/deploy-runbook.md#L175-L189

A 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 lift

Hardcoded hex colors instead of design tokens across the ported .astro components. Every reviewed .astro file mixes literal hex values (#F7F6F4, #100F11, #0B0A0C, #B9B8B6, #15151A, #100F12) with token references (var(--ink-900), var(--yellow-400)) in the same inline style strings — one root cause: the 1:1 design port didn't tokenize every color it introduced.

  • website/src/components/NavBar.astro#L61-L68: replace background:#100F11`` and stroke="#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/#100F12 gradient stops and color:#F7F6F4`` with tokens.
  • website/src/components/OpenSource.astro#L67-L107: replace color:#F7F6F4 and `background:`#0B0A0C with tokens.
  • website/src/components/OpenStandards.astro#L122-L128: replace background-color:#B9B8B6 (logo tint) and `color:`#F7F6F4 with tokens.
  • website/src/components/PostCard.astro#L63-L100: replace the repeated color:#F7F6F4`` with a token.

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/OpenSource.astro-97-103 (1)

97-103: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Self-hosting docs link uses docs.agenta.ai, contradicting the documented convention.

NavBar.astro explicitly documents that docs links must use https://agenta.ai/docs and not the docs.agenta.ai subdomain, and its own Docs nav link follows that rule. This "Self-hosting docs" CTA uses docs.agenta.ai/self-host/quick-start instead, 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 lift

Repeated 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 in src/styles/. #F7F6F4 alone 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 #F7F6F4 occurrence with the corresponding token(s).
  • website/src/components/SectionTitle.astro#L32-L36: replace the dark-branch #FFFFFF with a token, matching the light branch's var(--text-heading) pattern.
  • website/src/components/SiteNav.astro#L46-L56: replace #fff and #F7F6F4 with tokens.
  • website/src/components/TemplateExplorer.tsx#L17-L17: replace LOGO_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 .astro components.

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 win

Area tabs and harness switch aren't keyboard-accessible.

Both the template area tabs and the harness selector are plain <span onClick> elements — no tabIndex, no onKeyDown/Enter-Space handling, no role/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) with role="tab"/aria-selected (or aria-pressed for 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_KEY is not used here
website/.env.example says an empty key omits the PostHog snippet, but website/src/components/Analytics.astro still hardcodes the project key and only gates on import.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 to import.meta.env.PUBLIC_POSTHOG_KEY or remove this env var from the example.

website/src/layouts/Base.astro-5-8 (1)

5-8: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Implement the forwarded OG props and head slot

Site.astro passes ogType, ogImage, and a head slot, but Base.astro ignores all three. Add the matching props, render og:type/og:image in <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 win

Remove the inherited Cache-Control before the asset-specific rules.

/_astro/*, /fonts/*, /og/*, /icons/*, /logos/*, /blog/*, and /authors/* also match /*, so they inherit the page TTL unless Cache-Control is cleared first. Add ! Cache-Control in 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 win

Broken 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 immediate SyntaxError.

🐛 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 os
website/src/content/posts/the-guide-to-structured-outputs-and-function-calling-with-llms.mdx-139-157 (1)

139-157: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the OpenAI JSON-mode parameter. response_format="json" is not a valid Chat Completions value; use response_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 lift

Raw 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 from src/styles/ and never invent hexadecimal color values." All five pages hardcode #0E0D0F, #F7F6F4, #0A0A0B, #100F11, and various rgba(255,255,255,…) literals directly in inline style strings — yet the same files already reference var(--yellow-400), var(--ink-900), and var(--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 from src/styles/tokens*.css.
  • website/src/pages/authors/[slug].astro#L37-L73: replace the hero section's #0E0D0F/#F7F6F4 literals with tokens.
  • website/src/pages/authors/index.astro#L22-L38: replace the header section's #0E0D0F/#F7F6F4 literals with tokens.
  • website/src/pages/blog/index.astro#L33-L55: replace the header section's #0E0D0F/#F7F6F4 literals with tokens.
  • website/src/pages/contact.astro#L27-L48: replace the hero's #0E0D0F/#100F11/#F7F6F4 literals 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 win

Conversion proceeds even when WebP output is larger than the original.

There's no check comparing newSize to originalSize before deleting the source (line 129) and recording the result. image-manifest.json shows this isn't hypothetical: numerous images (e.g. the-ultimate-guide-for-chunking-strategies/img-17.png at -277.8%, img-18.png at -165.5%, top-10-techniques-to-improve-rag-applications/img-9.png at -167.7%) ended up substantially larger as WebP, and are now shipped that way to every visitor. Skip the conversion (keep the original) whenever newSize >= 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 win

Use 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 win

Reuse the shared site chrome on the homepage.

The homepage wires its own SiteNav, SiteFooter, and wrapper instead of using Site.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 reuse Site.astro and the shared NavBar, Footer, and CtaBand components 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 win

Update 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 win

Add the webhook relay step

repository_dispatch can’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 win

Pass dispatch payloads through env before using them in run. github.event.client_payload.variant_id, version_id, and app_slug are expanded into the shell here, so a malicious dispatch payload can inject commands or write outside prompts/. Use intermediate env vars, validate the slug, and fail curl on HTTP errors.

website/public/blog/prompt-management-for-non-engineers/hero.webp-1-1 (1)

1-1: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Move 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 lift

Keep 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 lift

Externalize 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 win

Use the shared design tokens for these colors.

#0E0D0F and #F7F6F4 are hard-coded hexadecimal values. Replace them with the corresponding variables from website/src/styles/tokens*.css.

As per coding guidelines, website/src/**/*.{astro,css,scss} must use the ported design tokens from src/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 win

Add 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 win

Add 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 win

Correct 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-1 to launch-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 win

Qualify the author-page finding.

This absolute statement conflicts with live-url-link-map.md and 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 win

Correct the Community link inventory.

The documented GitHub and Slack destinations differ from the current website/src/components/NavBar.astro and live-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 win

Mark resolved deltas or refresh this table.

The current-build comparison is stale relative to the supplied NavBar.astro and Footer.astro: real Resources/Community links, docs destinations, DPA, Trust Center, YouTube, Slack, and /authors routes 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 win

Route 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 win

Update 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 win

Remove 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 win

Show “Copied” only after writeText() resolves website/src/components/CopyPromptButton.tsx
onCopy sets 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 win

Placeholder dropdown links jump the page to top on click.

Resources/Community use href="#" 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 win

Copyright end year (2060) looks like a typo.

Copyright © 2020 – 2060 — 2060 is 34 years in the future from today; this reads like a 20262060 transposition. 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 win

Slack 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 win

Align the shared chrome guidance website/AGENTS.md still names NavBar/Footer, but website/src/layouts/Site.astro uses that pair while website/src/pages/index.astro uses SiteNav/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 win

Use the existing dark background design token.

Replace background:#0A0A0B`` with the corresponding src/styles/ token instead of embedding a hexadecimal value.

As per coding guidelines, website/src/**/*.{astro,css,scss} must “Use the ported design tokens from src/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 win

Raw 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 win

Heading 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 win

Multi-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 \n or 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 win

Use label for the production prompt pointer

Langfuse treats version as a numeric version, while production is a label. Change this to label="production" (or omit the argument, since production is the default).

website/src/pages/contact.astro-143-150 (1)

143-150: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Slack 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 win

Fix 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 win

Remove 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 win

Add spaces between adjacent Markdown spans.

The CTA currently concatenates words such as ?Agenta, deployment.Book, and demoand in 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 win

Remove 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 win

Use consistent SOC 2 terminology.

Standardize the article on SOC 2 Type I rather than mixing SOC2, SOC 2, and Type 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 win

Fix 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 win

Remove 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 win

Remove 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 win

Add descriptive title attributes 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 win

Add 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 only hero.webp and img-1.webp for 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 win

Point 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 win

Insert the missing space after the Product Hunt link.

The rendered text currently joins Product Hunt) and now, 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 win

Run 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 win

Restore 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 win

Use 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 win

Add semantic structure to both comparison tables.

Use <caption>, <thead>, and scope="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 win

Import os in the runnable example.

The snippet calls os.environ but never imports os, so copying it verbatim raises NameError before initialization.

Proposed fix
 import agenta as ag
+import os
 from opentelemetry.instrumentation.openai import OpenAIInstrumentor
website/src/content/posts/prompt-playground.mdx-25-25 (1)

25-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add 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 win

Update this snippet to the current OpenAI client API. openai.ChatCompletion.create is removed in openai-python 1.x; use from openai import OpenAI and client.chat.completions.create(...) instead.

🧹 Nitpick comments (7)
docs/design/marketing-website/research/current-repo-setup.md (1)

170-170: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Align 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 win

Replace 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 win

Duplicated 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 against r.chips.length.)

website/src/components/SiteNav.astro (1)

119-131: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Unbounded 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 scrollY against 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 passive scroll listener 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 win

Hardcoded machine-specific scratch path.

/tmp/claude-1000/-home-mahmoud-code-agenta/26f40a6a-8d2e-490f-9048-49f051a3bb87/scratchpad is 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 tradeoff

Nested lists can be mis-parsed.

The top-level <li> regex here isn't depth-aware, unlike blockToMd'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 in blockToMd for consistency and correctness on any future re-import.

website/scripts/optimize-images.mjs (1)

24-57: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add sharp as a direct dependency and drop the version-pinned pnpm path hack. website/package.json doesn’t declare sharp, so the current .pnpm/sharp@0.34.5/.33.5 lookup is brittle and will fail on the next bump. Import it normally once it’s added there.

Comment thread website/src/components/InlineCta.astro Outdated
Comment thread website/src/pages/pricing.astro Outdated
…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.
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:XXL This PR changes 1000+ lines, ignoring generated files. labels Jul 22, 2026
…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 &amp; last (no double-unescape), escape backslashes,
  repo-relative gitignored scratch dir (CodeQL + nitpick).
- .gitignore: ignore .scratch/.

Claude-Session: https://claude.ai/code/session_013Qe1Vf2yvj33BVd5W1q7HB
@mmabrouk

Copy link
Copy Markdown
Member Author

Review triage — website fixes (commit 83af02a0d1)

Thanks for the thorough pass. I went through every unresolved thread from CodeQL (github-advanced-security) and CodeRabbit. Summary of what landed, what was already fixed since the review, and what's intentionally out of scope. (Two sibling changes — the blog featured-row cards and the pruning of the docs/design/marketing-website/** research files — are handled by other in-flight commits on this branch; comments on those areas are noted below as handled elsewhere.)

Fixed in this commit

  • CtaBand.astro ignored Astro.props — real user-visible bug: /pricing and /contact pass a cta override through Site.astro, but the band hardcoded the landing copy. It now reads the props with the landing CTA as defaults, so /pricing shows "Start free, scale when you're ready" (verified in the built HTML).
  • PostHog gating (Analytics.astro / .env.example mismatch) — analytics now initializes only when PUBLIC_POSTHOG_KEY is set, the build is indexable (!PUBLIC_NOINDEX), and the host is the real site (agenta.ai/www.agenta.ai). Local dev, forks, and preview deploys no longer emit to our project — matching what .env.example already documented. Note: the production deploy must now set PUBLIC_POSTHOG_KEY.
  • public/_headers cache inheritance — correct: Cloudflare combines all matching rules and comma-joins duplicate headers, so /_astro/* etc. were shipping a malformed dual-max-age Cache-Control. Each asset block now clears the inherited header (! Cache-Control) before setting its own.
  • TemplateExplorer.tsx keyboard access — the area tabs and harness switch are now real <button>s with role="tab"/aria-selected (tabs) and aria-pressed (harness), so keyboard and screen-reader users can operate them.
  • OpenStandards.astro duplicated marquee chips — the second (decorative) copy is now aria-hidden + tabindex="-1", so links aren't announced/tabbed twice.
  • CopyPromptButton.tsxonCopy is async and only flips to "Copied" after writeText() resolves.
  • SiteFooter.astro — copyright end-year is now new Date().getFullYear() (was the stray 2060); the footer + /contact Slack links now use the real agenta-hq workspace invite instead of the generic join.slack.com.
  • tokens.css — quoted the fallback family names that tripped stylelint value-keyword-case.
  • optimize-images.mjs — skips the conversion and keeps the original when the WebP comes out no smaller (several images were shipping larger as WebP).
  • import-framer.mjs — hardened the two root escaping issues CodeQL flagged: decodeEntities now decodes &amp; last (no double-unescape), and escapeMdxText escapes backslashes first. Also replaced the hardcoded machine-specific scratch path with a gitignored repo-relative .scratch/.

Security findings (CodeQL) — remaining alerts on import-framer.mjs

import-framer.mjs is a one-shot, developer-run migration tool. It reads Agenta's own Framer CMS export through the Framer Server API and writes MDX that is committed and reviewed in the PR. It never runs in the deployed site and never processes untrusted end-user input at runtime. The two root escaping issues are fixed above (and improve any future re-import). The remaining alerts — "incomplete multi-character sanitization" around <iframe>/<script> and the framerusercontent.com substring check — concern raw HTML we intentionally preserve (YouTube <iframe> embeds) and a first-party CDN host check inside that offline tool. With no runtime path and first-party, human-reviewed output, these carry no exploitable surface; leaving the converter's lightweight regex tokenizer as-is (rather than swapping in a full HTML sanitizer that would rewrite already-reviewed output).

Already addressed since the review (stale)

  • Base.astro OG props + head slot — now fully implemented (og:type, og:image, <slot name="head" />).
  • SiteNav placeholder href="#" jump — the nav was reworked to real hover dropdowns with <button> triggers and real item links; there are no href="#" placeholders.
  • OpenSource.astro docs link / docs-domain convention — the current nav uses docs.agenta.ai as the canonical docs host, so the self-hosting CTA is consistent; the older agenta.ai/docs-only convention (from the since-deleted NavBar.astro) no longer applies.
  • index.astro "reuse Site.astro" — the landing reuses the shared SiteNav/SiteFooter/CtaBand components; it composes them directly (not via the Site.astro wrapper) specifically to get SiteNav's sticky-pill variant and its own full-bleed section frame. No chrome divergence.
  • docs/design/marketing-website/** reconciliation comments (STATUS/plan/DECISIONS/TASKS/blog-migration/site-inventory/site-capture, Vercel-vs-Cloudflare, launch-week dates, etc.) — these research files are being pruned from the PR by a separate curation commit, so the comments are mooted.

Not a policy violation

  • Migrated blog WebP assets under website/public/ — allowed. Per website/CLAUDE.md, Agenta's own marketing images (logos, migrated blog images) may live in the repo; only proprietary/licensed binaries (the GT Alpina / PP Mondwest fonts) are gitignored and injected at build time. Moving blog images to R2 is a possible future optimization, not a licensing requirement.

Intentional / out of scope for this pass

  • Design-token vs. inline hex (the recurring "use tokens, never invent a hex" comments across the .astro/.tsx components and pages) — acknowledged as tracked tech-debt from the 1:1 design port. A dedicated token/retheme pass is in progress separately; folding it in here would churn every component and collide with that work. Flagged for follow-up rather than fixed piecemeal in this review pass.
  • Blog post content/editorial nits (broken code samples, typos, missing CTA links, iframe titles, table semantics in the migrated *.mdx) — real but numerous content-quality items in migrated posts; they don't affect site function. Batched as an editorial follow-up. The three posts currently owned by the blog-cards commit are left to that change.
  • imprint.astro legal completeness (§ 5 TMG → § 5 DDG, managing director, Handelsregister, VAT ID) — the DDG is indeed the successor statute to the TMG, but the imprint mirrors the live Impressum verbatim and the missing fields need verified legal data. Flagged for Mahmoud's pre-launch legal pass rather than edited from a code review.
  • SiteNav rAF scroll loop — intentional cross-browser reliability tradeoff (documented in the component); per-tick cost is trivial. Left as-is.

Re-review requested below.

@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

mmabrouk added 2 commits July 22, 2026 16:38
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.
@mmabrouk
mmabrouk merged commit 7b38504 into main Jul 22, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Frontend size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants