Skip to content

feat: Bob AI#671

Draft
surajshetty3416 wants to merge 319 commits into
developfrom
ai-delight-demo
Draft

feat: Bob AI#671
surajshetty3416 wants to merge 319 commits into
developfrom
ai-delight-demo

Conversation

@surajshetty3416

Copy link
Copy Markdown
Member

Bob is an AI assistant that helps you with building complete website from scratch.

- and show conditionally show AI features using this flag
- Remember model selection
Move preset selector inside popup and make it look optional
- Only support open router for now
- Do not send complete page YAML for summary message
- Send selections always
- Remove model categorisation
surajshetty3416 and others added 29 commits July 5, 2026 21:46
…losing paren)

The fontFamily normalizer split on the first comma to strip a fallback stack,
then returned early — before the paren-reclose guard. When the model baked a
fallback INSIDE the var (var(--suraj-font-inter, Inter) — which the prompt bans
but Gemini does anyway), the split truncated it to 'var(--suraj-font-inter',
dropping the ). Invalid CSS, so the published page silently fell back to serif
while the editor's lenient inline styles auto-closed it and looked fine.

fontFamily now extracts the token handle with a regex and returns var(--id)
clean, only splitting on comma for literal family stacks. Fixed in both the
server normalizer (page_writer) and its frontend port (normalizeStyles.ts);
repaired the live page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Oversized heading and heavy bordered pills -> a subtle sparkle, a small
text-sm heading tucked under it, and compact hover-fill suggestion rows.
Restrained espresso look; same behaviour (tap prefills the prompt).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The stripped-down text rows looked unfinished (left-aligned under a centered
heading, no tappable affordance). Give them a resting surface-gray-2 fill, an
arrow-up-right glyph, and a guidance subtitle; full-width soft chips that
darken on hover.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…more gap

Final pass on the suggestion chips per feedback: sparkle up to size-7, drop
the arrow glyph, bump the suggestion text to text-p-base, and open the gap
between chips (gap-2 + py-2) so they breathe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Delete builder/ai/cassette.py and strip its hooks from llm.py. The layer was
added earlier this session, had its UI removed on request, and never earned
its keep — zero tests used it, no API surface (console-only arming), and it
was flagged as dead weight in review. Footprint was fully self-contained
(only the module + llm.py), so complete()/complete_with_tools() collapse back
to clean litellm wrappers. The provider-cache work (provider_kwargs, cache
breakpoints) is untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The earlier options-as-text guard missed this: the lead-in 'Let's explore
three additional typography options...' starts with no choose/pick/which word
and has no '?', so it slipped through, and the [fonts: X + Y] markup — the
exact format option_text() replays a card in — wasn't a recognized signal.

Broaden the guard: presenting lead-ins (here are / let's explore / consider
these / a few options) now count, and any leaked option-decoration marker
([fonts:/palette:/layout:/image:) on a 2+-bullet no-tool round triggers the
corrective round. Still one correction per turn, still no-tool-round only, so
genuine change-summaries with bullets don't trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…icker

The freeform 'add any number of swatches' color_input was unclear and let the
model spread colours randomly. Replace it with LABELLED role slots the model
defines (Brand/Primary, Background, Accent, Text/Ink — adapted per brand),
each rendered with Builder's own ColorInput (swatch + hex field + popover
picker) instead of the raw native input. The reply now maps each colour to
its role verbatim ('Brand: #C4552D, Background: #F4EFE8').

Prompt: user-assigned colours are LAW — each is used in EXACTLY the role the
user named, across every layout option's palette, the minted tokens (one per
role, hex verbatim), and the built page. The model may only fill blank slots
(a neutral, derived tints/shades), never reassign or replace a filled slot,
unless the user explicitly says to.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Colors/Fonts/Dimensions tabs now show how many tokens each holds. The count
is search-independent (stable while filtering within a tab) and hides when a
type is empty.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…andle

A hover-revealed copy button on every Design System token row writes the
token's CSS handle var(--<id>) to the clipboard, so it can be pasted straight
into a style field. Shows a check tick for ~1.2s on success. Verified live:
copies var(--wander-accent) etc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The typography prompt listed named example fonts, so the model kept grabbing
the front-runners (Yeseva One / Unbounded / Fraunces + Albert Sans / Hanken
Grotesk / Instrument Sans) for every brand. Banning specific names would just
shift the repetition to the next three.

Reframe: derive the pairing FROM the brand — first fix the brand's type
personality in a phrase, then pick faces that embody it (a bakery, a law firm,
a synth label must never get the same trio). The font list is now explicitly a
RANGE to show the spread, not a shortlist to grab the first three of, widened
with more options. Added the anti-pattern by name and a self-check: if your
three picks would fit a totally different brand equally well, they're wrong.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fixed generic trio (bakery/portfolio/landing page) is replaced by a wider,
more characterful pool sampled 3-at-a-time per mount, so the panel feels fresh
each visit instead of always the same three. Separate pools for build (fresh
page) and edit (page with content).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each empty-state suggestion is now {label, prompt}: the chip stays short but
clicking it prefills a complete brief — brand name, vibe, and the section list
— so the agent has what it needs to proceed with minimal follow-up questions
(name/direction/sections are already answered). Still an editable starting
point. Edit-mode suggestions likewise expand to specific instructions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two related complaints: a detailed brief still triggered layout+typography+
details cards it had already answered, and the plan card just restated the
brief before a redundant 'Build it' gate.

- Design cards are now CONDITIONAL: the agent first triages what the brief
  already gives (name/purpose/vibe/sections/colours) and asks ONLY the cards
  it genuinely leaves open. A rich brief needs zero or one card (usually just
  typography); a bare request may need the full set. The details form is
  skipped entirely when the brief lists the sections.
- The plan card is removed. There's no plan/approval step — once the agent
  has the essentials it BUILDS directly, carrying the full working brief into
  generate_page's brief arg. The user watches it build live and can Revert.
  Change requests before build fold into the brief instead of re-prompting.

Multi-page/rebrand plan in the orchestrator (already conditional/rare) stays.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A full Stillpoint site was built but the page kept its placeholder title
'Color Card Test' and a default pages/<id> route — the agent never gave the
page an identity, so it looked like it didn't understand what it built.

The FOUNDATION build round now also calls set_page_settings to set
page_title = the brand, route = a clean brand slug, and a one-line
meta_description. A page built for a brand must never keep a placeholder
title or default route, unless the user set one themselves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A form the agent builds (contact/booking/signup) can now actually persist
submissions. New confirm-gated connect_form tool provisions the whole chain on
approval: a private submissions DocType (System Manager only, NO guest read),
a Frappe Web Form bound to it (the guest-safe, rate-limited, field-whitelisted
boundary — login_required off), and a page client script that POSTs the form's
fields to the stock Web Form accept endpoint. The owner reads entries in Desk
at /app/<doctype>, surfaced as a link in the agent's summary.

Safety: guests never insert directly and can't read submissions back; unsafe
fieldtypes (Link/Table/Attach) are coerced to Data; Frappe's accept endpoint
enforces the field whitelist + 10/min rate limit + ignore_permissions insert.
No app-code deploy — DocType and Web Form are created at runtime.

Verified end-to-end in console: propose->confirm->apply creates the chain, a
Guest submit lands a record, no guest permission is granted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A full-bleed page (e.g. an all-black design) set its background only on the
root <div>, so everything the div didn't cover — the preview screenshot's
1280x720 canvas, a short page's tail, overscroll — fell through to the
browser's default white. Preview cards showed white leaking around dark pages.

get_context now extracts the root block's background (color, var(--token), or
gradient) and the template paints html,body with it, so the page fills the
viewport. None when the root sets no background (unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…'t white

The prior fix set html/body background via a <style> rule, but CSS background
propagation to the canvas meant a stylesheet rule on html didn't reach the
overscroll area (getComputedStyle(html) stayed white on the live page) — so
scrolling past the top of a dark page still rubber-banded white. Setting the
background as an inline style on the <html> element itself bypasses the
propagation quirk: html now computes the page colour and the overscroll canvas
follows it. The <style> body rule stays for the body box.

Verified on the published Frame page: html background went from white to
rgb(13,13,13).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A form field the agent called 'Name' scrubs to 'name' — Frappe's reserved
primary key — so DocType creation threw 'Fieldname name is restricted' on
Apply. Now reserved fieldnames are remapped for the DocType (name -> name_field)
while the form input keeps its own name attribute; the wiring script carries an
input-name -> fieldname map so the guest submit still routes to the right field.
No model round-trip, no data mismatch.

Verified: a 'name' field creates as 'name_field', a guest submit with the
mapped key lands a record, and the generated script maps name -> name_field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…+ DOM-ready)

The tool created the DocType/Web Form/script but the form never saved. Five
real bugs, found by driving the live form end-to-end:

- The script targeted an invented selector (.reservation-form) and required
  name attrs the agent never set. Now it FINDS the form (given selector, else
  the tightest container with a submit control + ~N inputs) and maps inputs to
  fields POSITIONALLY (preferring a matching name attr). No DOM pre-wiring.
- The script loads in <head>, before the form is parsed — findForm() ran too
  early. Now it waits for DOMContentLoaded.
- It only listened for the form 'submit' event; now it also binds the submit
  button's click (busy-flag dedupes).
- Select fields rejected the insert (HTML <select> submits its option value,
  not the DocType's Select option label → validation 417). Dropdowns are now
  stored as Data, which accepts any chosen value.
- attach_form_script's update path used db.set_value, which doesn't regenerate
  the served .js file; now it save()s so re-runs actually update the script.

Prompt: list fields in FORM ORDER; form_selector is a best-effort hint.
Verified: filling the live Stillpoint form + submit lands a record (200).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ted the page

Live case (Groove Vault): after the user picked layout + typography, the agent
ran its build turn — searched images, minted 5 design tokens, set page settings,
added a script — then stopped with 'Added a script.' It never called
generate_page, so the page has zero blocks.

New one-shot corrective round: when a page turn minted design tokens but the
page is still EMPTY and generate_page was never called, the model is told to
call generate_page now with the full brief before finishing. Independent of the
no-op guard, since this turn did mutate (tokens/scripts).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…he doctype

Live case (Groove Vault): the user asked 'where is all the booking submissions?'
— a READ — and the agent proposed creating a SECOND DocType ('Groove Vault
Listening Booth Reservation') even though the form already saves to 'Groove
Listening Booth Reservation'.

- connect_form now detects an already-wired form on the page (via its
  'Save <doctype> submissions' script) and, unless force_new is set, declines
  with the existing DocType's Desk link so the model answers the question rather
  than creating a duplicate. force_new added for a genuinely separate form.
- Prompt: a question about where a form's submissions go / how to see entries is
  a read — find the DocType and reply with /app/<slug>, never connect_form.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ace-*-7)

The status indicator dot used bg-ink-green-5, which isn't a real utility, so it
rendered invisible — leaving a gap that read as stray left padding before the
label. Switched the dot to the solid bg-surface-*-7 status colours so it shows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Show a Font token as its friendly name in violet (like Text Color shows
'Ink Dark Blue') instead of the raw var(--uuid), with a specimen 'A'
prefix rendered in the resolved family. Add a 'Save as Token' action to
the dropdown so a plain family can be promoted to a Font token in place,
alongside the existing Upload Font action.

New FontInput/FontInputActions mirror ColorInput/NewBuilderToken; the
Family control swaps its inline Autocomplete for FontInput. Autocomplete's
ActionButton label/handler/icon become optional (component-only actions).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two bugs stranded cost display on US$ even when the site is INR:

- format.ts read a non-reactive module var, so cost lines rendered
  before the currency resource resolved (slow on a cold FX-rate cache)
  stayed USD forever. Make it a reactive ref so they re-format on load.
- usd_rate used @redis_cache, which memoizes None too — a single FX
  timeout poisoned the cache and forced USD for 24h. Cache only on
  success.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RVQc23yyNmnviAMJ3mXbvC
Make watching Bob build feel alive, while keeping every status truthful.

- AIBuildOverlay: ambient canvas layer during a build (top aurora bloom
  + scanning beam + breathing frame) with a top-centre narration pill
  and a one-shot completion flourish. Rendered inside .page-builder so
  --toolbar-height resolves (teleporting to body collapsed the region).
- BobOrb: empty-state hero orb as a self-contained WebGL shader —
  translucent, flowing blue-violet aurora; CSS fallback, reduced-motion
  aware, GL context cleaned up on unmount.
- Live tool status: subscribe to ai_chat_tool_activity so a long
  tool-calling round narrates real per-tool work ("Set --color-primary",
  "Read block: Hero") instead of a frozen "Thinking…". Only real backend
  signals drive the pill — no invented step labels.
- Removed the redundant header heartbeat dot and the pill's decorative
  typing-dots ellipsis.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RVQc23yyNmnviAMJ3mXbvC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant