Skip to content

feat(frontend): playground-native agent onboarding - #5076

Merged
mmabrouk merged 26 commits into
big-agentsfrom
fe-feat/agent-onboarding
Jul 6, 2026
Merged

feat(frontend): playground-native agent onboarding#5076
mmabrouk merged 26 commits into
big-agentsfrom
fe-feat/agent-onboarding

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

What this adds

Agent onboarding for the big-agents branch, all behind env flags so nothing changes for existing users until enabled.

The headline is playground-native onboarding: a first-run user landing on the project-scoped /playground gets a guided surface instead of the generic empty playground. The left panel offers templates, the right panel asks "what do you want to build?". Describing an agent (or picking a template) mints an ephemeral agent, then commits it in place into a real agent you can immediately chat with. No redirect, no separate create screen.

Earlier screens in the same arc are also here: the agent Home onboarding (a create-agent composer + template gallery) and the connect-a-model / provider-key wiring the chat needs to actually run.

What's in here

Playground-native onboarding (NEXT_PUBLIC_AGENT_PLAYGROUND_ONBOARDING)

  • Runs inside the real Playground via a useAgentOnboarding hook (mints an ephemeral agent, drives the ephemeral→real transition), so it reuses all the existing playground machinery rather than a parallel mount.
  • Commit is in place: useCreateAgent grew an onCommitted callback so onboarding swaps the entity and updates the URL with history.replaceState instead of navigating.
  • The right panel IS the agent chat. "What do you want to build?" is an AgentChatEmptyState state; on submit it shows the description as an optimistic user turn + a loading placeholder, so the switch reads as one continuous chat.
  • "Browse all templates" opens the full gallery in place (reusing Home's TemplatesSection) instead of navigating away.
  • "Continue in IDE" surfaces the install command + the prompt as a streamed assistant bubble, then disables the composer with a "Start over" so the flow isn't a dead end.

Agent Home onboarding (NEXT_PUBLIC_AGENT_ONBOARDING)

  • First-run Home with a create-agent composer, template gallery, and usage/agents tables. Templates can either open a config-review drawer or (via NEXT_PUBLIC_AGENT_TEMPLATE_BUILDER) seed the builder directly.
  • IDE-handoff modal for the composer.

Agent chat run-readiness

  • Connect-a-model banner + composer gating: the chat reads the agent's model provider, checks the vault for that provider's key, and disables the composer until connected. The provider-key check is deferred until an agent is actually committed.

Theme palette source of truth (chore, phases 1–2)

  • palette.ts becomes the single source for semantic color roles; a generator emits the Tailwind/antd token files. Prep for dark mode.

Shared extractions

  • EntityCard catalog tile, SectionRail fill mode + exposed drawer primitives, and RichChatInput made configurable for non-chat inputs.

Transitions

The onboarding surfaces enter/leave with consistent motion instead of popping: a Reveal fade+rise for once-on-mount surfaces (hero, gallery, composer), the grid-rows 0fr↔1fr height idiom for appear/disappear chrome (connect-model banner, queued messages, approval dock), a height-0→auto stagger for the agent config sections, and a settling skeleton that holds the config slot until the real config resolves.

Notes

  • All work is tsc + eslint clean under Node 24. Package changes (@agenta/ui, @agenta/entity-ui) build clean.
  • No live end-to-end run yet. This is a draft for review of the FE structure and the flag-gated flows.
  • A temporary [agent-onboarding] console diagnostic is still in useAgentOnboarding / useCreateAgent for verifying the in-place-vs-redirect branch. It comes out before this leaves draft.

What to QA

Enable NEXT_PUBLIC_AGENT_ONBOARDING and NEXT_PUBLIC_AGENT_PLAYGROUND_ONBOARDING.

  • Open a fresh project. You land on the onboarding playground (templates left, "what do you want to build?" right), not the generic "Start your playground" empty state.
  • Type a description, click Create agent. The text becomes a sent user turn and the page stays put (URL updates to the app playground, no navigation). Picking a template does the same.
  • "Browse all templates" swaps the right panel for the full gallery in place; picking a card commits like the quick list.
  • "Continue in IDE": your prompt shows as a user turn, an assistant bubble gives the install command, the composer disables, and "Start over" returns to the hero.
  • With no provider key, the "Connect OpenAI…" banner appears only after commit and animates in; adding a key collapses it out.
  • From the onboarding playground, create/switch to a new empty project. You get a fresh onboarding, not an empty playground.
  • Regression: with both flags off, /apps and /playground behave exactly as before.

ardaerzin added 15 commits July 6, 2026 01:32
Pull the catalog-tile layout (icon + title/adornment, 2-line description,
category pills + meta slot) out of CatalogAppCard into a reusable EntityCard
in @agenta/ui, and refit CatalogAppCard on top of it. Lets other
"pick from a grid" surfaces (agent-home templates) share the same tile
without duplicating the markup.
Add a getMarkdown() imperative handle (read content without submitting),
a right-aligned trailing toolbar slot, and props to tune the editor for
description-style inputs: minHeightClassName, textSizeClassName,
hideShortcutHints, and submitOnEnter. Defaults preserve the existing
chat-composer behavior.
Add a @agenta/entity-ui/drawers/shared subpath export and a barrel so
app-layer surfaces can reuse the drawer rail/field primitives instead of
re-implementing them. Add a `fill` prop to SectionRail that stretches it
into a bounded flex parent (min-h-0 flex-1) so the content panel can host
an internally-scrolling child, and re-export SectionRail from the root.
Introduce the agent onboarding Home page (composer, template gallery +
setup drawer, your-agents table, usage summary, on-ramps) under
components/pages/agent-home, plus a full templates gallery route. Both are
gated by the NEXT_PUBLIC_AGENT_ONBOARDING flag: the /apps Home route
renders AgentHome instead of the legacy AppManagement dashboard when the
flag is on, and the /agent-templates route redirects Home when it is off.
Wire the EE templates page to the OSS one and give the templates gallery
the bounded full-height layout frame.
…-type mismatch

The createEphemeralAppFromTemplate helper was hardcoding is_llm=true for all
templates, causing agent templates to be typed as "llm" workflows instead of
"agent". Now set is_llm based on the template type: false for agents, true
otherwise, so workflowType() returns the correct handler key.
Wire the agent Home composer and template cards to a real create flow
(useCreateAgent): create the ephemeral, commit it to a real agent app,
stash a first-run seed on the new revision, and land in its playground —
no drawer. The setup-drawer path is retained behind a renamed flag.

- Rename NEXT_PUBLIC_AGENT_ONBOARDING -> NEXT_PUBLIC_AGENT_TEMPLATE_BUILDER:
  when on, a template card skips the config-review drawer and seeds the
  playground with a builder instruction; off keeps the drawer flow.
- Home + templates gallery now render unconditionally (flag no longer
  gates the page).
- Add agentFirstRunSeedAtom, produced here and consumed by the chat.
Detect whether the vault holds a key for the agent's model provider
(useAgentModelKeyStatus) and, when it doesn't, surface a connect-a-model
banner above the composer and disable the composer until connected.
"Set up credentials" flips the playground to Build and opens the Model &
harness drawer via the new openAgentConfigSectionAtom; saving the key
clears the gate reactively.

Also consume the first-run seed: a freshly-created agent surfaces its
starting prompt in the empty state (not the composer) with a Start CTA,
and auto-starts once the model gate clears (connecting the key is the
user's go-ahead — no second click).
…gent config panel

Let the user connect a model provider key without leaving the playground:
add a ProviderKeyField to the Model & harness drawer that saves to the
project vault and refetches, and a "Model / Provider key" rail that lands
on the key tab when a key is missing. AgentTemplateControl consumes
openAgentConfigSectionAtom so the chat's connect-a-model banner opens
straight onto it.

Surface model-section status: an amber "Connect key" incomplete tone /
badge when the provider key is missing, a red "No model"/"Unavailable"
when the model is missing or unsupported. Adds a status dot to SectionRail
and a titleBadge slot to ConfigAccordionSection to carry the pills.
Reworks the harness picker from cards to a [rail | detail] layout.
…olving

The provider-key gate read the static provider catalog (standardSecretsAtom),
whose keys are empty until vaultSecretsQueryAtom lands — so a playground reload
flashed a false connect-a-model banner, disabled composer, and Connect key
section warnings until the query resolved. Suppress every missing-key assertion
(modelBlocked, ConnectModelBanner, providerNeedsKey) until the vault data is an
array; an empty-but-loaded vault still blocks, and a fetch error no longer
false-gates.
…(phase 1)

Extract the theme colors currently scattered across theme-variables.css and
ThemeContextProvider into a single palette.ts (light + dark). This is a
lossless extraction — dark values antd's darkAlgorithm derives are snapshotted
to their exact current output, so the app looks identical and every dark value
is directly editable.

Add generate-tailwind-tokens.ts to emit the theme artifacts from palette.ts.
Neither is consumed yet: the generator writes to a scratch dir by default
(GEN_OUT to target the live tree), so it can't collide with in-flight edits.
Replace the composer's clipboard-copy "Continue in IDE" action with a proper
IDE-handoff modal (install command + the user's prompt, Copy button). Uses a
declarative antd Modal so it inherits the app theme (dark-safe, unlike the
static Modal.* helpers).

Rework AgentComposer from a segmented Build/IDE switch to a two-button footer
(Continue in IDE + primary Create agent), mirroring the playground onboarding
composer. useAgentHomeActions drops the clipboard handler; the page owns the
modal via useIdeHandoffModal.
Add an opt-in onboarding flow (NEXT_PUBLIC_AGENT_PLAYGROUND_ONBOARDING) that
lives INSIDE the playground instead of on the agent-home page. First-run users
land on an ephemeral agent at the project /playground route: the config panel
shows a template list, the chat surface shows a "what do you want to build?"
composer. Sending commits the ephemeral into a real agent IN PLACE (no
redirect) and hands off to the live chat as one continuous conversation.

- OnboardingEntry decides before painting (redirect first-run, list for
  returning) so we never flash the wrong surface; OnboardingLoader is the one
  "setting up" screen across every boundary.
- Playground gains an `onboarding` mode: useAgentOnboarding mints/drives the
  ephemeral, injects the onboarding panels via MainLayout's renderConfigOverride
  + AgentGenerationPanel, and exposes the ephemeral→real transition through
  OnboardingContext. Chrome (session bar, config forms) hides while ephemeral.
- appUtils gains `deferInspect` so the ephemeral renders immediately and
  refines schemas in the background.
- Chat: optimistic first turn during commit, autoSend seed (explicit "go" sends
  once the model is ready), a dedicated onboarding chat scope + resetScope so a
  prior visit's session never leaks in, and a streamed "Continue in IDE" bubble.
Wire the generator into the app so palette.ts actually drives theme colors,
completing the phase-1 extraction. The generator now writes the live
theme-variables.css and a new theme/antd-overrides.generated.ts, and
ThemeContextProvider consumes the generated dark-token overrides instead of
its own inline DARK_TOKEN_OVERRIDES block. Adds legacy-shim.ts as the frozen
--ag-c-* codemod input the generator re-emits.

- generate:tailwind-tokens runs with GEN_WRITE=1 so it targets the live tree.
- Regenerated theme-variables.css from palette.ts (no visual change).
- Docs (root + web AGENTS.md, oss README, dark-mode.md) now point to palette.ts
  as the single source of truth: edit it + regenerate, never hand-edit the
  generated files.
Swap the static antd `message` import for the `App.useApp()` instance in
ListOfProjects and the Projects settings page. The static helper renders
outside the ConfigProvider tree, so its toasts show unstyled (light) in dark
mode; the context instance inherits the app theme.
Smooth the ephemeral→real handoff and template browsing in the onboarding
playground so nothing pops or snaps in.

- Reveal / RevealCollapse primitives + ConfigAccordionSection `revealOnMount`
  (opt-in, staggered) fade the config sections and composer chrome in on mount
  instead of popping when the panel resolves after commit.
- OnboardingBrowseTemplates renders the full gallery in place (right panel)
  instead of navigating to the standalone page; picking a card commits the
  ephemeral in place, same path as the left quick-pick list.
- OnboardingConfigSettling shows a config-shaped skeleton for the beat between
  commit and the real config resolving, so the panel swaps in once cleanly.
- Wire the transition through OnboardingContext / useAgentOnboarding and reuse
  TemplatesSection; ConnectModelBanner latches its content through the collapse.
@vercel

vercel Bot commented Jul 5, 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 6, 2026 12:33pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 607352e5-3c4f-4cc4-bb87-45e750f2da2d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR introduces a palette-driven theme token generation pipeline (palette.ts, generator script, generated CSS/antd overrides), a playground-native onboarding flow for creating agents from an ephemeral state, a new agent-home page with template gallery and setup drawer, model-harness provider-key configuration UI, and supporting shared UI primitives and fixes.

Changes

Theme Token Generation Pipeline

Layer / File(s) Summary
Documentation updates
AGENTS.md, web/AGENTS.md, docs/designs/dark-mode.md, web/oss/README.md
Documents the new palette.ts-driven workflow: edit source of truth, regenerate, and never hand-edit generated theme files.
Palette source-of-truth module
web/oss/src/styles/theme/palette.ts
Defines typed light/dark semantic roles, shadows, scale ramps, alpha fills, and feature-family tokens aggregated into a default palette export.
Legacy shim and generator script
web/oss/src/styles/theme/legacy-shim.ts, web/scripts/generate-tailwind-tokens.ts, web/package.json
Adds a frozen legacy --ag-c-* shim and a script that builds theme CSS and antd overrides from palette.ts, including dark aliasing and a parity harness.
Generated outputs and provider consumption
web/oss/src/styles/theme-variables.css, web/oss/src/styles/theme/antd-overrides.generated.ts, web/oss/src/components/Layout/ThemeContextProvider.tsx
Regenerates theme CSS variables and dark overrides, and switches ThemeContextProvider to import them instead of inline definitions.

Estimated code review effort: 4 (Complex) | ~75 minutes

Playground Onboarding and Agent-Home Experience

Layer / File(s) Summary
Onboarding state, scope, and reveal primitives
.../OnboardingContext.tsx, .../Reveal.tsx, .../OnboardingLoader.tsx, state/scope.tsx, state/sessions.ts, state/firstRunSeed.ts
Adds onboarding context, scope isolation, session reset, and first-run seed atom used across the onboarding flow.
useAgentOnboarding orchestration hook
.../useAgentOnboarding.ts
Mints an ephemeral agent, wires playground selection/URL state, exposes a commit flow to convert to a real agent, and derives config readiness.
Onboarding config panel and browse-templates UI
.../OnboardingConfigPanel.tsx, .../OnboardingConfigSettling.tsx, .../OnboardingBrowseTemplates.tsx
Renders template selection buttons, a config-settling skeleton, and an in-place template gallery for pre-commit onboarding.
Playground and router wiring
Playground.tsx, PlaygroundRouter/index.tsx, MainLayout/index.tsx, PlaygroundHeader/index.tsx, Layout/Layout.tsx
Wires onboarding mode into Playground, routes /playground to onboarding, adds renderConfigOverride, and hides chrome/controls during onboarding.
Agent chat panel onboarding integration
AgentChatPanel.tsx, ConnectModelBanner.tsx, RevealCollapse.tsx, useAgentModelKeyStatus.ts, AgentChatEmptyState.tsx
Adds model-key gating, optimistic first-turn UI, IDE handoff, first-run auto-start, and a connect-model banner.
Agent-home page, composer, and hooks
pages/agent-home/index.tsx, OnboardingEntry.tsx, AgentComposer/*, ContinueInIdeModal.tsx, EmptyAgents.tsx, OnRamps.tsx, UsageSummary/*, YourAgentsTable/*, hooks
Implements the agent-home landing page with first-run vs returning states, composer, IDE handoff, and agent listing.
Template assets and gallery UI
assets/templates.ts, TemplatesGallery/*, TemplatesSection/*, TemplateSetupDrawer/*
Defines starter agent templates and renders a searchable template gallery plus a setup drawer for connecting integrations.

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

Model Harness and Provider-Key Configuration UI

Layer / File(s) Summary
Open-config-section atom and drawer wiring
openConfigSection.ts, agenta-shared/state/index.ts, AgentTemplateControl.tsx
Adds a shared atom to remotely open config drawer sections and readiness indicator/badge UI.
Provider key field and model harness integration
ProviderKeyField.tsx, useModelHarness.tsx
Adds vault-backed provider API key UI and integrates it into a rail/detail harness with model/credentials tabs.
Shared drawer/entity-card primitives
SectionRail.tsx, drawers/shared/index.ts, EntityCard.tsx, CatalogAppCard.tsx
Adds status indicators to SectionRail, a shared primitives barrel, and a reusable EntityCard used by CatalogAppCard.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Supporting UI/API Fixes

Layer / File(s) Summary
App.useApp() message migration
ListOfProjects.tsx, settings/Projects/index.tsx
Switches from direct antd message import to App.useApp().
Ephemeral app deferred inspection
appUtils.ts
Adds deferInspect option to seed immediately and refine schemas asynchronously.
RichChatInput enhancements
RichChatInput.tsx
Adds getMarkdown() and new layout/behavior props (trailing, submitOnEnter, etc.).
ConfigAccordionSection reveal animation
ConfigAccordionSection.tsx
Adds titleBadge and mount-reveal animation props.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AgentHome
  participant useTemplateSelect
  participant useCreateAgent
  participant TemplateSetupDrawer
  participant Playground

  AgentHome->>useTemplateSelect: select template
  useTemplateSelect->>useCreateAgent: create agent (builder mode)
  useCreateAgent->>useCreateAgent: mint ephemeral, commit real revision
  useCreateAgent->>Playground: navigate to playground with seed
  AgentHome->>TemplateSetupDrawer: open setup (non-builder mode)
  TemplateSetupDrawer->>useCreateAgent: onCreate({template, name})
  useCreateAgent->>Playground: navigate with created agent
Loading
sequenceDiagram
  participant PlaygroundRouter
  participant useAgentOnboarding
  participant AgentChatPanel
  participant OnboardingContext

  PlaygroundRouter->>useAgentOnboarding: active=true, mint ephemeral agent
  useAgentOnboarding->>OnboardingContext: expose commit(), browseAll, chromeRevealed
  AgentChatPanel->>OnboardingContext: read commit state, chromeHidden
  AgentChatPanel->>useAgentOnboarding: commit(seedMessage)
  useAgentOnboarding->>useAgentOnboarding: convert ephemeral to real revision
  useAgentOnboarding->>AgentChatPanel: real entityId ready, chrome revealed
Loading

Possibly related PRs

  • Agenta-AI/agenta#4577: Both PRs modify dark-theme override plumbing tied to DARK_TOKEN_OVERRIDES/ThemeContextProvider.
  • Agenta-AI/agenta#4903: Both PRs modify AgentChatPanel's queued-message rendering/animation behavior.
  • Agenta-AI/agenta#4983: Both PRs modify AgentChatPanel.tsx and shared session state in web/oss/src/components/AgentChatSlice/state/sessions.ts.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly matches the main change: frontend playground-native agent onboarding.
Description check ✅ Passed The description is detailed and directly aligned with the onboarding, theme, and shared UI changes in the PR.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fe-feat/agent-onboarding

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.

At commit the session bar, connect-model banner and header mode switch all
revealed in the same frame the first message sent, so they fought the send and
the transcript scroll. Gate that post-commit chrome on a delayed `chromeRevealed`
signal (500ms after the real revision is set) so it eases in once the message
has landed, and hand the heavy entity swap (`setEntityIds`) to `startTransition`
so React yields to the browser and the commit animations aren't starved.

@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: 10

🧹 Nitpick comments (12)
web/packages/agenta-entity-ui/src/drawers/shared/SectionRail.tsx (1)

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

Status dot conveys state via color only.

No text alternative for the warning/invalid dot, unlike the Tooltip-wrapped connection dots in CatalogAppCard.tsx. Screen-reader users get no signal that the item needs attention.

♿ Proposed fix to add an accessible label
                             {item.status ? (
-                                <span
+                                <span
+                                    role="img"
+                                    aria-label={item.status === "invalid" ? "Invalid" : "Needs attention"}
                                     className={`h-1.5 w-1.5 shrink-0 rounded-full ${
                                         item.status === "invalid"
                                             ? "bg-[var(--ag-colorError)]"
                                             : "bg-[var(--ag-colorWarning)]"
                                     }`}
                                 />
                             ) : item.count != null ? (
web/oss/src/components/pages/agent-home/index.tsx (1)

29-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor duplication: composer-read logic repeated.

composerRef.current?.getMarkdown().trim() ?? "" is duplicated here and in useAgentHomeActions.readPrompt. Consider exposing readPrompt from useAgentHomeActions (or a small shared helper) and reusing it for onContinueInIde to avoid drift.

web/oss/src/components/AgentChatSlice/components/ConnectModelBanner.tsx (1)

13-22: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Multi-line comment exceeds guideline terseness.

This 10-line JSDoc block goes well beyond "at most one short line per comment." The explanation of why the banner is always-mounted (lines 19-21) is a legitimate surprising-constraint callout, but the rest (lines 13-18) is standard prop/behavior description that could be trimmed to a single line.

As per coding guidelines, web/**/*.{ts,tsx,js,jsx}: "Keep code comments terse: at most one short line per comment, with multi-line explanatory comments avoided unless a genuinely surprising constraint must be documented."

Source: Coding guidelines

web/oss/src/components/pages/agent-home/assets/templates.ts (2)

1-5: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Multi-line file-level comment exceeds terseness guideline.

This 4-line block comment is purely descriptive (not a surprising constraint) and could be condensed to one line.

As per coding guidelines, web/**/*.{ts,tsx,js,jsx}: "Keep code comments terse: at most one short line per comment, with multi-line explanatory comments avoided unless a genuinely surprising constraint must be documented."

Source: Coding guidelines


47-52: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Additional multi-line comments (builderMessage field doc, templateBuilderMessage function doc).

Same terseness guideline applies here — both blocks span multiple lines describing non-surprising behavior.

As per coding guidelines, web/**/*.{ts,tsx,js,jsx}: "Keep code comments terse: at most one short line per comment... unless a genuinely surprising constraint must be documented."

Also applies to: 79-84

Source: Coding guidelines

web/oss/src/components/pages/agent-home/components/TemplateSetupDrawer/ToolsPreview.tsx (1)

7-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Multi-line JSDoc exceeds terseness guideline.

This 5-line comment describes design intent that isn't a genuinely surprising constraint; could be trimmed to one line.

As per coding guidelines, web/**/*.{ts,tsx,js,jsx}: "Keep code comments terse: at most one short line per comment, with multi-line explanatory comments avoided unless a genuinely surprising constraint must be documented."

Source: Coding guidelines

web/oss/src/components/pages/agent-home/components/TemplatesGallery/index.tsx (1)

101-108: 📐 Maintainability & Code Quality | 🔵 Trivial

TODO: wire template creation to actually mint the agent.

handleTemplateCreate currently just shows a toast instead of creating the ephemeral agent and opening the playground, per the TODO(Phase B) comment. Confirm this is intentionally deferred and tracked, since as written "Create agent" produces no functional outcome.

Want me to wire this to useCreateAgent/useAgentOnboarding now, or open a follow-up issue to track it?

web/oss/src/components/pages/agent-home/OnboardingEntry.tsx (1)

35-39: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Unconditional Playground chunk prefetch runs for returning users too.

This effect fires on every mount of OnboardingEntry, regardless of whether the user is first-run or returning. The comment states the intent is to prefetch before the first-run redirect, but returning users (who render <AgentHome /> here) also pay this download even though they may never navigate to the ephemeral onboarding /playground. Consider gating the prefetch on firstRun (or loading, since the decision isn't known yet) so it doesn't unconditionally cost bandwidth for the common returning-user path.

⚡ Proposed fix
     useEffect(() => {
-        void import("`@/oss/components/Playground/Playground`")
-    }, [])
+        if (loading || firstRun) {
+            void import("`@/oss/components/Playground/Playground`")
+        }
+    }, [loading, firstRun])
web/oss/src/pages/w/[workspace_id]/p/[project_id]/apps/agent-templates.tsx (1)

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

No loading fallback for the dynamically imported TemplatesGallery.

Without a loading option, next/dynamic renders nothing until the chunk downloads, producing a blank page flash on this route — inconsistent with the OnboardingLoader pattern used elsewhere in this onboarding flow (e.g., apps/index.tsx's OnboardingEntry).

💡 Proposed fix
+import OnboardingLoader from "`@/oss/components/pages/agent-home/PlaygroundOnboarding/OnboardingLoader`"

 const TemplatesGallery = dynamic(
     () => import("`@/oss/components/pages/agent-home/components/TemplatesGallery`"),
+    {loading: OnboardingLoader},
 )
web/oss/src/pages/w/[workspace_id]/p/[project_id]/apps/index.tsx (1)

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

AgentHome dynamic import has no loading fallback, unlike OnboardingEntry.

OnboardingEntry is given {loading: OnboardingLoader} so the chunk-load is covered by a spinner, but AgentHome (the default path when PLAYGROUND_NATIVE_ONBOARDING is off) has no loading option. Per Next.js docs, without a loading callback, next/dynamic "sends a minimal placeholder to the browser" and only renders once the chunk downloads — i.e., a blank screen flash for all users landing on /apps in the default (flag-off) configuration.

💡 Proposed fix
-const AgentHome = dynamic(() => import("`@/oss/components/pages/agent-home`"))
+const AgentHome = dynamic(() => import("`@/oss/components/pages/agent-home`"), {
+    loading: OnboardingLoader,
+})
web/oss/src/components/pages/agent-home/PlaygroundOnboarding/OnboardingLoader.tsx (1)

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

Consider announcing the loading state to assistive tech.

This is the single reused loading surface across every onboarding boundary (redirect, chunk load, ephemeral mint). Adding role="status"/aria-live="polite" would let screen-reader users hear "Setting up your agent…" instead of silently waiting.

♿ Suggested addition
 const OnboardingLoader = () => (
-    <div className="flex h-[calc(100dvh-46px)] w-full flex-col items-center justify-center gap-3">
+    <div
+        role="status"
+        aria-live="polite"
+        className="flex h-[calc(100dvh-46px)] w-full flex-col items-center justify-center gap-3"
+    >
         <Spin />
         <span className="text-xs text-[var(--ag-colorTextSecondary)]">Setting up your agent…</span>
     </div>
 )
web/package.json (1)

68-68: 🗄️ Data Integrity & Integration | 🔵 Trivial

Consider running the parity harness by default when regenerating live theme files.

GEN_WRITE=1 now writes directly to the live theme-variables.css and antd-overrides.generated.ts with no BASELINE_CSS set, so parityCheck() (generate-tailwind-tokens.ts lines 447-472) is skipped by default — a bad palette.ts edit could silently overwrite the live theme without any mismatch report. Since git diff review is the fallback safety net, this is more a guardrail improvement than a blocker.

🛡️ Optional: default to a parity check on regenerate
-        "generate:tailwind-tokens": "GEN_WRITE=1 tsx scripts/generate-tailwind-tokens.ts"
+        "generate:tailwind-tokens": "GEN_WRITE=1 BASELINE_CSS=oss/src/styles/theme-variables.css tsx scripts/generate-tailwind-tokens.ts"

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6298c86b-b2bb-47b5-8e26-8f75d0781480

📥 Commits

Reviewing files that changed from the base of the PR and between 1756d3d and d187af1.

📒 Files selected for processing (80)
  • AGENTS.md
  • docs/designs/dark-mode.md
  • web/AGENTS.md
  • web/ee/src/pages/w/[workspace_id]/p/[project_id]/apps/agent-templates.tsx
  • web/oss/README.md
  • web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
  • web/oss/src/components/AgentChatSlice/components/AgentChatEmptyState.tsx
  • web/oss/src/components/AgentChatSlice/components/ConnectModelBanner.tsx
  • web/oss/src/components/AgentChatSlice/components/RevealCollapse.tsx
  • web/oss/src/components/AgentChatSlice/hooks/useAgentModelKeyStatus.ts
  • web/oss/src/components/AgentChatSlice/state/firstRunSeed.ts
  • web/oss/src/components/AgentChatSlice/state/scope.tsx
  • web/oss/src/components/AgentChatSlice/state/sessions.ts
  • web/oss/src/components/Layout/Layout.tsx
  • web/oss/src/components/Layout/ThemeContextProvider.tsx
  • web/oss/src/components/Playground/Components/MainLayout/index.tsx
  • web/oss/src/components/Playground/Components/PlaygroundHeader/index.tsx
  • web/oss/src/components/Playground/Playground.tsx
  • web/oss/src/components/PlaygroundRouter/index.tsx
  • web/oss/src/components/Sidebar/components/ListOfProjects.tsx
  • web/oss/src/components/pages/agent-home/OnboardingEntry.tsx
  • web/oss/src/components/pages/agent-home/PlaygroundOnboarding/OnboardingBrowseTemplates.tsx
  • web/oss/src/components/pages/agent-home/PlaygroundOnboarding/OnboardingConfigPanel.tsx
  • web/oss/src/components/pages/agent-home/PlaygroundOnboarding/OnboardingConfigSettling.tsx
  • web/oss/src/components/pages/agent-home/PlaygroundOnboarding/OnboardingContext.tsx
  • web/oss/src/components/pages/agent-home/PlaygroundOnboarding/OnboardingLoader.tsx
  • web/oss/src/components/pages/agent-home/PlaygroundOnboarding/Reveal.tsx
  • web/oss/src/components/pages/agent-home/PlaygroundOnboarding/useAgentOnboarding.ts
  • web/oss/src/components/pages/agent-home/assets/constants.ts
  • web/oss/src/components/pages/agent-home/assets/templates.ts
  • web/oss/src/components/pages/agent-home/components/AgentComposer/index.tsx
  • web/oss/src/components/pages/agent-home/components/ContinueInIdeModal.tsx
  • web/oss/src/components/pages/agent-home/components/EmptyAgents.tsx
  • web/oss/src/components/pages/agent-home/components/OnRamps.tsx
  • web/oss/src/components/pages/agent-home/components/TemplateSetupDrawer/IntegrationRow.tsx
  • web/oss/src/components/pages/agent-home/components/TemplateSetupDrawer/ModelRow.tsx
  • web/oss/src/components/pages/agent-home/components/TemplateSetupDrawer/SetupRow.tsx
  • web/oss/src/components/pages/agent-home/components/TemplateSetupDrawer/ToolsPreview.tsx
  • web/oss/src/components/pages/agent-home/components/TemplateSetupDrawer/index.tsx
  • web/oss/src/components/pages/agent-home/components/TemplatesGallery/TemplateSection.tsx
  • web/oss/src/components/pages/agent-home/components/TemplatesGallery/index.tsx
  • web/oss/src/components/pages/agent-home/components/TemplatesSection/ProviderMarks.tsx
  • web/oss/src/components/pages/agent-home/components/TemplatesSection/TemplateCard.tsx
  • web/oss/src/components/pages/agent-home/components/TemplatesSection/TemplateCategoryChips.tsx
  • web/oss/src/components/pages/agent-home/components/TemplatesSection/index.tsx
  • web/oss/src/components/pages/agent-home/components/TutorialVideoEmbed.tsx
  • web/oss/src/components/pages/agent-home/components/UsageSummary/index.tsx
  • web/oss/src/components/pages/agent-home/components/YourAgentsTable/columns.tsx
  • web/oss/src/components/pages/agent-home/components/YourAgentsTable/index.tsx
  • web/oss/src/components/pages/agent-home/hooks/useAgentHomeActions.ts
  • web/oss/src/components/pages/agent-home/hooks/useAgentHomeVariants.ts
  • web/oss/src/components/pages/agent-home/hooks/useCreateAgent.ts
  • web/oss/src/components/pages/agent-home/hooks/useIdeHandoffModal.tsx
  • web/oss/src/components/pages/agent-home/hooks/useTemplateSelect.ts
  • web/oss/src/components/pages/agent-home/index.tsx
  • web/oss/src/components/pages/settings/Projects/index.tsx
  • web/oss/src/lib/helpers/dynamicEnv.ts
  • web/oss/src/pages/w/[workspace_id]/p/[project_id]/apps/agent-templates.tsx
  • web/oss/src/pages/w/[workspace_id]/p/[project_id]/apps/index.tsx
  • web/oss/src/styles/theme-variables.css
  • web/oss/src/styles/theme/antd-overrides.generated.ts
  • web/oss/src/styles/theme/legacy-shim.ts
  • web/oss/src/styles/theme/palette.ts
  • web/package.json
  • web/packages/agenta-entities/src/workflow/state/appUtils.ts
  • web/packages/agenta-entity-ui/package.json
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/AgentTemplateControl.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/agentTemplate/ProviderKeyField.tsx
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/agentTemplate/useModelHarness.tsx
  • web/packages/agenta-entity-ui/src/drawers/shared/CatalogAppCard.tsx
  • web/packages/agenta-entity-ui/src/drawers/shared/SectionRail.tsx
  • web/packages/agenta-entity-ui/src/drawers/shared/index.ts
  • web/packages/agenta-entity-ui/src/index.ts
  • web/packages/agenta-shared/src/state/index.ts
  • web/packages/agenta-shared/src/state/openConfigSection.ts
  • web/packages/agenta-ui/src/RichChatInput/RichChatInput.tsx
  • web/packages/agenta-ui/src/components/EntityCard.tsx
  • web/packages/agenta-ui/src/components/index.ts
  • web/packages/agenta-ui/src/components/presentational/section/ConfigAccordionSection.tsx
  • web/scripts/generate-tailwind-tokens.ts

Comment on lines +434 to +441
const handleCreateAgent = useCallback(() => {
if (!onboarding || onboarding.committing) return
const text = richInputRef.current?.getMarkdown().trim() ?? ""
setPendingFirstTurn(text || null)
// The text becomes the sent first turn — clear the composer so it doesn't linger into the chat.
richInputRef.current?.setMarkdown("")
onboarding.commit(text)
}, [onboarding])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check whether commit() in useAgentOnboarding guards against empty/blank seed text
fd useAgentOnboarding.ts --exec cat -n {}

Repository: Agenta-AI/agenta

Length of output: 12075


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the Create Agent button and the create/commit path.
files=(
  "web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx"
  "web/oss/src/components/AgentChatSlice/hooks/useCreateAgent.ts"
)

for f in "${files[@]}"; do
  echo "===== $f ====="
  wc -l "$f"
  echo
done

echo "===== AgentChatPanel relevant lines ====="
sed -n '400,470p' web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx

echo
echo "===== useCreateAgent ====="
cat -n web/oss/src/components/AgentChatSlice/hooks/useCreateAgent.ts

Repository: Agenta-AI/agenta

Length of output: 453


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "===== search for useCreateAgent ====="
rg -n "useCreateAgent" web/oss/src

echo
echo "===== AgentChatPanel create button / handleCreateAgent ====="
rg -n "handleCreateAgent|Create agent|Create Agent|disabled=|onboarding.commit\\(" web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx

echo
echo "===== AgentChatPanel outline ====="
ast-grep outline web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx --view expanded | sed -n '1,240p'

Repository: Agenta-AI/agenta

Length of output: 2995


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "===== useCreateAgent ====="
wc -l web/oss/src/components/pages/agent-home/hooks/useCreateAgent.ts
cat -n web/oss/src/components/pages/agent-home/hooks/useCreateAgent.ts

echo
echo "===== AgentChatPanel around handleCreateAgent and Create agent button ====="
sed -n '424,450p' web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
sed -n '1438,1452p' web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx

Repository: Agenta-AI/agenta

Length of output: 8331


Guard Create agent against blank composers. handleCreateAgent still calls onboarding.commit(text) when the composer is empty, and useCreateAgent only skips the first-turn seed when seedMessage is blank. Add a disabled/early-return guard so the button can’t create an agent with no input.

Comment thread web/oss/src/components/AgentChatSlice/AgentChatPanel.tsx
Comment thread web/oss/src/components/pages/agent-home/components/OnRamps.tsx
Comment thread web/oss/src/components/pages/agent-home/hooks/useCreateAgent.ts
Comment on lines +117 to +151
const commit = useCallback(
(seedMessage: string, name?: string) => {
if (!entityId || committing || realEntityId) return
setCommitting(true)
// Surface the seed so the chat can render it as an optimistic user turn during commit.
setCommittingSeed(seedMessage.trim() || null)
void createAgent({
name,
seedMessage,
entityId,
// Create-agent is an explicit "go" → the chat sends the description as the first turn
// once the model is ready (no extra Start click), keeping the transition seamless.
autoSendSeed: true,
onCommitted: ({appId, revisionId}) => {
// Flip the onboarding state urgently — the settling skeleton, the `chromeRevealed`
// timer, and the commit-failure recovery all read `realEntityId` synchronously.
setRealEntityId(revisionId)
// Hand the heavy part (the playground re-rendering the real entity → config panel +
// generation surface) to a transition, so React can yield to the browser and the
// commit's CSS animations aren't starved by a blocking render.
startTransition(() => {
setEntityIds([revisionId])
})
if (typeof window !== "undefined") {
window.history.replaceState(
window.history.state,
"",
`${baseAppURL}/${appId}/playground?revisions=${revisionId}`,
)
}
},
}).finally(() => setCommitting(false))
},
[entityId, committing, realEntityId, createAgent, setEntityIds, baseAppURL],
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

committingSeed is never cleared when commit fails, leaving a stale optimistic chat turn.

useCreateAgent (see web/oss/src/components/pages/agent-home/hooks/useCreateAgent.ts) catches its own errors internally and only calls onCommitted on success — on failure it just shows a message.error and resolves normally. So .finally(() => setCommitting(false)) always runs, but committingSeed (set at Line 122) is only ever cleared implicitly by a successful commit setting realEntityId. On failure, committing goes back to false while realEntityId stays null and committingSeed stays set — per the type's own doc comment ("shows it as an optimistic user turn"), the chat is left showing a message that was never actually sent, with no indication that the commit failed.

🐛 Proposed fix
     const commit = useCallback(
         (seedMessage: string, name?: string) => {
             if (!entityId || committing || realEntityId) return
             setCommitting(true)
             setCommittingSeed(seedMessage.trim() || null)
+            let committed = false
             void createAgent({
                 name,
                 seedMessage,
                 entityId,
                 autoSendSeed: true,
                 onCommitted: ({appId, revisionId}) => {
+                    committed = true
                     setRealEntityId(revisionId)
                     startTransition(() => {
                         setEntityIds([revisionId])
                     })
                     if (typeof window !== "undefined") {
                         window.history.replaceState(
                             window.history.state,
                             "",
                             `${baseAppURL}/${appId}/playground?revisions=${revisionId}`,
                         )
                     }
                 },
-            }).finally(() => setCommitting(false))
+            }).finally(() => {
+                setCommitting(false)
+                if (!committed) setCommittingSeed(null)
+            })
         },
         [entityId, committing, realEntityId, createAgent, setEntityIds, baseAppURL],
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const commit = useCallback(
(seedMessage: string, name?: string) => {
if (!entityId || committing || realEntityId) return
setCommitting(true)
// Surface the seed so the chat can render it as an optimistic user turn during commit.
setCommittingSeed(seedMessage.trim() || null)
void createAgent({
name,
seedMessage,
entityId,
// Create-agent is an explicit "go" → the chat sends the description as the first turn
// once the model is ready (no extra Start click), keeping the transition seamless.
autoSendSeed: true,
onCommitted: ({appId, revisionId}) => {
// Flip the onboarding state urgently — the settling skeleton, the `chromeRevealed`
// timer, and the commit-failure recovery all read `realEntityId` synchronously.
setRealEntityId(revisionId)
// Hand the heavy part (the playground re-rendering the real entity → config panel +
// generation surface) to a transition, so React can yield to the browser and the
// commit's CSS animations aren't starved by a blocking render.
startTransition(() => {
setEntityIds([revisionId])
})
if (typeof window !== "undefined") {
window.history.replaceState(
window.history.state,
"",
`${baseAppURL}/${appId}/playground?revisions=${revisionId}`,
)
}
},
}).finally(() => setCommitting(false))
},
[entityId, committing, realEntityId, createAgent, setEntityIds, baseAppURL],
)
const commit = useCallback(
(seedMessage: string, name?: string) => {
if (!entityId || committing || realEntityId) return
setCommitting(true)
// Surface the seed so the chat can render it as an optimistic user turn during commit.
setCommittingSeed(seedMessage.trim() || null)
let committed = false
void createAgent({
name,
seedMessage,
entityId,
// Create-agent is an explicit "go" → the chat sends the description as the first turn
// once the model is ready (no extra Start click), keeping the transition seamless.
autoSendSeed: true,
onCommitted: ({appId, revisionId}) => {
committed = true
// Flip the onboarding state urgently — the settling skeleton, the `chromeRevealed`
// timer, and the commit-failure recovery all read `realEntityId` synchronously.
setRealEntityId(revisionId)
// Hand the heavy part (the playground re-rendering the real entity → config panel +
// generation surface) to a transition, so React can yield to the browser and the
// commit's CSS animations aren't starved by a blocking render.
startTransition(() => {
setEntityIds([revisionId])
})
if (typeof window !== "undefined") {
window.history.replaceState(
window.history.state,
"",
`${baseAppURL}/${appId}/playground?revisions=${revisionId}`,
)
}
},
}).finally(() => {
setCommitting(false)
if (!committed) setCommittingSeed(null)
})
},
[entityId, committing, realEntityId, createAgent, setEntityIds, baseAppURL],
)

Comment on lines +65 to +69
export const border = {
default: {light: "#bdc7d1", dark: "#424242"}, // [absorbs] --ag-c-BDC7D1, zinc-4
secondary: {light: "#eaeff5", dark: "#303030"},
split: {light: "rgba(5, 23, 41, 0.06)", dark: "rgba(253, 253, 253, 0.12)"},
} satisfies Record<string, Pair>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

git ls-files 'web/oss/src/styles/theme/*' 'web/**/generate-tailwind-tokens.ts' | sed -n '1,200p'

Repository: Agenta-AI/agenta

Length of output: 323


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
paths = [
    Path('web/oss/src/styles/theme/palette.ts'),
    Path('web/oss/src/styles/theme/legacy-shim.ts'),
    Path('web/oss/src/styles/theme/generate-tailwind-tokens.ts'),
]
for p in paths:
    print(f'## {p} ##')
    if p.exists():
        lines = p.read_text().splitlines()
        for i, line in enumerate(lines[:320], 1):
            if 'border' in line or 'aliasDark' in line or 'BDC7D1' in line or 'zinc' in line or 'absorbs' in line or 'legacy-shim' in line:
                pass
        print(f'lines={len(lines)}')
    else:
        print('MISSING')
PY

Repository: Agenta-AI/agenta

Length of output: 328


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path

targets = {
    'web/oss/src/styles/theme/palette.ts': [('border.default', 1), ('zinc', 1), ('BDC7D1', 1)],
    'web/oss/src/styles/theme/legacy-shim.ts': [('BDC7D1', 2)],
    'web/oss/src/styles/theme/generate-tailwind-tokens.ts': [('aliasDark', 2), ('resolve', 2)],
}

for file, needles in targets.items():
    p = Path(file)
    print(f'\n### {file} ###')
    if not p.exists():
        print('MISSING')
        continue
    lines = p.read_text().splitlines()
    for needle, pad in needles:
        hits = [i for i, line in enumerate(lines, 1) if needle in line]
        if not hits:
            continue
        for i in hits[:3]:
            start = max(1, i - pad)
            end = min(len(lines), i + pad)
            print(f'-- around line {i} for {needle!r} --')
            for j in range(start, end + 1):
                print(f'{j:4}: {lines[j-1]}')
PY

Repository: Agenta-AI/agenta

Length of output: 1539


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
p = Path('web/scripts/generate-tailwind-tokens.ts')
print(f'exists={p.exists()} lines={len(p.read_text().splitlines()) if p.exists() else "NA"}')
if p.exists():
    lines = p.read_text().splitlines()
    needles = ['aliasDark', 'legacy-shim', 'return', '===', 'exact', 'resolve', 'token']
    hits = []
    for i, line in enumerate(lines, 1):
        if 'aliasDark' in line or 'legacy' in line or 'resolve' in line:
            hits.append(i)
    for i in hits[:20]:
        start = max(1, i-8)
        end = min(len(lines), i+20)
        print(f'\n-- around line {i} --')
        for j in range(start, end+1):
            print(f'{j:4}: {lines[j-1]}')
PY

Repository: Agenta-AI/agenta

Length of output: 30343


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
p = Path('web/scripts/generate-tailwind-tokens.ts')
print(f'exists={p.exists()} lines={len(p.read_text().splitlines()) if p.exists() else "NA"}')
if p.exists():
    lines = p.read_text().splitlines()
    hits = [i for i, line in enumerate(lines, 1) if 'aliasDark' in line or 'legacy' in line or 'resolve' in line]
    for i in hits[:20]:
        start = max(1, i-8)
        end = min(len(lines), i+20)
        print(f'\n-- around line {i} --')
        for j in range(start, end+1):
            print(f'{j:4}: {lines[j-1]}')
PY

Repository: Agenta-AI/agenta

Length of output: 30343


border.default shouldn’t claim to absorb --ag-c-BDC7D1 in dark mode. legacy-shim.ts keeps that token at #2f2f2f, and the generator only aliases shim tokens when they resolve to the exact same dark value as a role. If this legacy token should track border.default.dark, update the shim value to #424242; otherwise remove it from the absorb comment.

Comment thread web/scripts/generate-tailwind-tokens.ts Outdated
ardaerzin added 5 commits July 6, 2026 13:27
The theme generator hand-copied palette's dark seed/link/shadow/elevated/placeholder
values into DARK_TOKEN_OVERRIDES, so editing palette.ts silently would not update the
generated --ag-* seed CSS vars. Derive the object from palette and reuse it for both the
darkAlgorithm seed and buildAntdOverrides, restoring the single-source-of-truth guarantee.
Generator output is byte-identical before/after.
The home composer called createAgent with no shared lock, so a rapid double-click could
mint and commit two agents. Add an in-hook in-flight latch so every caller (composer,
builder cards, setup drawer) is protected regardless of UI-level disabling.
createEphemeralAppFromTemplate had no .catch, so a rejected mint (or a null id) left ready
false forever and the onboarding loader spun with no recovery. Add error handling that
releases the mint guard, surfaces the failure, and exposes error/retry; OnboardingLoader
now renders a Try again affordance instead of hanging.
The vault write was awaited with no catch, so a failed save for this security-sensitive
credential gave the user no feedback. Add a catch that shows an error message and keeps
the typed value so the user can retry.
OnRamps rendered both cards with no handlers, so first-run users got two no-op buttons.
Wire Bring an existing app to the observability page, and render each card only when its
handler is present (the unwired demo card is hidden) so there are no dead buttons.
streamIdeBubble's recursive setTimeout chain had no teardown, so unmounting mid-animation
kept calling setMessages on a stale closure. Track the timer and clear it on unmount.
@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 6, 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.

@ardaerzin
ardaerzin marked this pull request as ready for review July 6, 2026 11:55
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. Feature Request New feature or request Frontend labels Jul 6, 2026
On a failed onboarding commit, committingSeed was left set — inert today only because the
chat's recovery effect clears the local optimistic turn separately. Clear it at the source
so the hook state stays self-consistent and no stale sent turn can be re-surfaced.
@mmabrouk
mmabrouk merged commit 472295c into big-agents Jul 6, 2026
23 checks passed
mmabrouk added a commit that referenced this pull request Jul 10, 2026
mmabrouk added a commit that referenced this pull request Jul 10, 2026
mmabrouk added a commit that referenced this pull request Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature Request New feature or request Frontend size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants