website: Add Electric Agents app landing page#4499
Conversation
Adds APP_PAGE_PLAN.md outlining the rewrite of website/app.md from a downloads index into a product landing page that explains what the desktop and mobile apps actually do: multi-server / multi-device, bundled Horton coding agent, state explorer + tile workspace for SDK builders, and attach-to-remote flows for software-factory-style workloads (CI / webhooks / GitHub issues / cron). Also adds an `App` entry to the main nav in MegaNav.vue and MegaNavMobile.vue, in its own visual group between Sync and Cloud with a `'|'` divider on each side. Plain link to /app; no dropdown panel since the page is self-contained. No user-facing copy on /app changes yet — follow-up PRs land the page sections per the plan. Co-authored-by: Cursor <cursoragent@cursor.com>
Mobile won't launch alongside the /app page rewrite, so §7 ships as a single "Mobile · Preview" card pointing at packages/agents-mobile on GitHub rather than speculative TestFlight / internal-testing links. Propagated the preview framing through the §1 hero glyph row, the priority list, the page-structure overview, PR 5 of the implementation plan, and the open questions block. Also fixed five drift bugs flagged in the self-review: the §2 note no longer claims "software factory" appears in the hero sub-copy (the §4 hero copy already dropped it), §8 no longer claims to reorder CTA buttons that aren't being reordered, the §4 multi-device diagram drops the stray "web" device, and §3.5 scenario 1 lists "review" rather than "merge" as an app-side action. Co-authored-by: Cursor <cursoragent@cursor.com>
Restructures §7 as a single pull request worked through in six logical
phases instead of six independent PRs. Phases are a working aid for the
author and reviewer — the diff lands together when the branch is opened
for review. Notes that phase 1's plan doc and nav entry are already on
the branch, so the remaining work continues against the same branch.
Also fixes two readability nits surfaced during the final review:
- The §63 cross-reference to "the hero copy in §4" was ambiguous (§4 of
the doc vs §4 of the page). Disambiguated to "the page hero (see §1
Hero in the section-by-section block below)".
- The §7 mobile Preview body copy was described from two angles but
never pinned to a final string. Locked the exact body string and CTA
label so the phase that ships §7 has nothing left to author.
Propagated the phases terminology through §6 ("Visual assets"), §9
("Open questions"), and the phase-2 hero-copy cross-reference.
Co-authored-by: Cursor <cursoragent@cursor.com>
…n shells Phase 1 of the /app page rewrite (see APP_PAGE_PLAN.md §7). Pure structural change — no user-facing copy or visual content changes land in this commit beyond the addition of the new section shells. - Adds <AdPlaceholder> — a dashed-border, soft-bg, mono-labelled block that stands in for content slots while later phases fill them in. Carries a data-placeholder attribute so reviewers can find each slot in the diff and so we can grep for unfilled slots later. - Inserts six <Section> shells between the existing hero and the download blocks: §2 visual strap · §3 three ways to use it · §3.5 scenarios · §4 multi-device · §5 bundled Horton · §6 built for builders. Each shell carries an id (visual / three-ways / scenarios / multi-device / horton / builders) so we can deep-link to it during development and so phase 6 can wire up redirects. - Wraps the existing desktop / mobile / canary download blocks as §7 in comments. Their copy and id anchors (#desktop / #mobile / #canary) are untouched so any external links still resolve. The mobile sub-section keeps its existing "Coming soon" framing for now — a later phase reframes it as "Mobile · Preview" linking to packages/agents-mobile on GitHub. Verified end-to-end in vitepress dev: the page renders cleanly, all existing download CTAs still work, and the new #three-ways / #builders anchors resolve correctly. Co-authored-by: Cursor <cursoragent@cursor.com>
Phase 2 of the /app page rewrite (see APP_PAGE_PLAN.md §7 phase 2). Hero copy is locked to the final headline + sub described in APP_PAGE_PLAN.md §1: Run, observe and steer your agents. Desktop and mobile clients for the Electric Agents platform — one app to code with Horton, attach to remote sessions, and build your own agents on the infra and SDK. The word "agents" carries the brand accent treatment from <AgentsHero>. The previous "Electric Agents App" product-name H1 is dropped in favour of the new headline — the product name is now carried by the nav entry instead. Adds a five-platform glyph row under the CTAs (macOS · Windows · Linux · iOS · Android) as muted icon + mono-label pairs. The iOS and Android glyphs are slightly desaturated and share a single "Preview" pill positioned beneath them, communicating the mobile apps' preview status without cluttering each individual glyph. The platforms grid uses an explicit 2-row CSS grid so the preview pill stays anchored under the mobile pair on any width. Restructures §2 from a single placeholder block into a desktop + mobile placeholder pair (16:10 + 9:16) with the locked caption "Same session. Two devices. One control plane." underneath. The grid uses `minmax(0, …)` columns so the placeholders' aspect-ratio + intrinsic content widths can't push the strap past the section's max-width. Phase 5 will swap each AdPlaceholder for the real screenshot without touching the surrounding chrome. Also renames the lower CSS section headings to match the new §7 numbering (§3 mobile → §7b mobile, §4 canary → §7c canary). No runtime behaviour change from the rename. Co-authored-by: Cursor <cursoragent@cursor.com>
Self-review of phases 1 and 2. The biggest issue surfaced was an internal inconsistency between the new hero glyph row (which marks iOS + Android as "Preview") and the §7b mobile sub-section (which still said "Coming soon" with disabled App Store / Google Play badges). Same iOS + Android, two different framings on the same page. Resolves that by landing the §7 Mobile · Preview card now rather than deferring it to phase 5. Final-copy body string and CTA are already locked in APP_PAGE_PLAN.md §7, so no new design work is needed: - §7b sub-section eyebrow changes from `Mobile · Coming soon` to `Mobile · Preview`. - Two-card iOS + Android grid (disabled App Store / Play badges) is replaced by a single content card with the locked body string + a `View on GitHub →` CTA pointing at packages/agents-mobile on the default branch. - Drops the now-unused MobilePlatform type, mobilePlatforms data array, the .ad-icon--appstore / --googleplay mask definitions, and the .ad-mobile-grid / .ad-mobile-card / .ad-mobile-icon / .ad-mobile-name / .ad-soon-pill / .ad-store-badge / .ad-store-glyph CSS rules + their media-query partners. Net delta is -46 lines despite adding the new card markup. Also fixes a few smaller review findings: - The .ad-hero-platforms style comment claimed a 3-column responsive collapse that the code doesn't implement. Replaced with an honest note that the 5-column layout is preserved at all widths and compresses cleanly to ~360px. - The §2 visual strap was passing .ad-visual-strap-desktop / -mobile classes to the AdPlaceholder pair but never styling them. Dead classes removed. - AdPlaceholder's `name` prop jsdoc now documents the two valid conventions in use today: section identifier (e.g. "§3 — Three ways to use it") for full-section placeholders, or asset filename (e.g. "desktop-hero.png") for image / SVG slots that match the final path under website/public/img/app/. - Tightened the now-stale "Phase 1 placeholder block" template comment and the §7 wrapper comment so both describe the current state rather than phase-1-vs-future-phase posture. No new copy or visuals are introduced beyond what APP_PAGE_PLAN.md §7 already locked for the mobile sub-section. Co-authored-by: Cursor <cursoragent@cursor.com>
…ders Lands the three deepest copy sections on the /app rewrite: §3 "Three ways to use it." — three side-by-side mode cards (Code locally · Attach remotely · Build with the SDK), each with the locked body copy, a four-item "You can:" anchor list, and a brand-tinted lucide icon. A muted centred strip below the grid restates the one-integrated-platform takeaway. §3.5 "What this looks like in practice." — four scenario cards in a 2×2 grid on a dark Section. Each card stacks a 16:9 placeholder illustration slot (filled in phase 5), a `Touches · …` mono eyebrow, the scenario title, and the locked body paragraph. "Software factory" appears in scenario 1 as planned. §6 "Built for builders." — six compact 3×2 cards covering tile workspace, state explorer, entity timeline, MCP & skills, local discovery and the CLI installer. Each carries a lucide icon, short feature description and a "Use it to…" hint anchored to the card bottom by a dashed divider. Adds nine lucide Iconify mask URLs (code-2, radio-tower, microscope, layout-grid, database, history, cable, radar, terminal) following the existing `.ad-icon--*` pattern. Adds responsive breakpoints so each grid collapses sensibly: modes 3 → 2 → 1, scenarios 2 → 1, builders 3 → 2 → 1. All claims are still backed by the §5 mapping in APP_PAGE_PLAN.md; no new features promised. Section orientation comment marks §3 / §3.5 / §6 as complete, leaving §4 / §5 for phase 4. Co-authored-by: Cursor <cursoragent@cursor.com>
Catches three plan-deviations and two lying CSS comments in the phase-3 commit (e6259b8), keeping the rendered page aligned with the locked copy in APP_PAGE_PLAN.md. Copy fixes: - §3 card 3 title: "Build agents on the SDK." → "Build your own agents." The previous draft inherited a prepositionally-awkward "on the SDK" form and didn't mirror cards 1 + 2 (verb + object + adverbial). The new title connects to the body's "the entities _you_ write" emphasis and reads cleanly next to the eyebrow. APP_PAGE_PLAN.md §3 locks the new title and records the prior rejected variant. - §3 list-label: "You can" → "You can:" (all three cards). The trailing colon matches the plan literal and reframes the mono-uppercase label as a list-introducer rather than a peer eyebrow. - §3.5 touches eyebrow: "Touches · …" → "Touches: …" (all four cards). The colon restores label semantics — `Touches` is the field name, the dot-separated items are its value. The previous middle-dot put `Touches` on the same axis as the items it was meant to introduce. CSS comment fixes: - `.ad-modes-grid` block comment: equal-bottom alignment is the product of TWO mechanisms (`align-items: stretch` on the grid AND `margin-top: auto` on the list LABEL). The old comment credited stretching alone; the new comment names both and notes why each is insufficient on its own. - `/* §3.5 scenarios */` block comment: dropped the false claim that the dark section background "tints" the cards, replaced with an honest description of how `:dark="true"` forces dark variables for the section's subtree. Updated the `Touches · …` example to match the new `Touches: …` markup. - `.ad-scenarios-card` rule comment: removed the "card reads as a light surface above the alt fill" line — in dark mode the card bg (`--vp-c-bg`) is one rung BELOW the section's `--ea-surface-alt` fill, so cards read as recessed panels, not elevated tiles. The new comment names that explicitly and points at `.ad-mobile-preview-card` for the same convention. No layout or visual regressions; verified §3 and §3.5 still render correctly in dark mode (the only mode supported today per AGENTS.md landing-pages context). Co-authored-by: Cursor <cursoragent@cursor.com>
Closes the last phase 3 gap. The plan promises (lines 63, 525) that
"software factory" appears in three places on the page:
1. §2 pitch block (phase 5 — copy lands with real assets)
2. §3 "Attach remotely" (in card body — already shipped ✓)
3. §3.5 scenario 1 (was MISSING — fixed here)
The plan's own locked scenario 1 body just forgot to include the
phrase even though three other places in the plan called it out as
the named home for that frame. Catching this on the phase 3 review
pass.
Reframes the scenario's lead sentence:
before: "A new GitHub issue (or `issue_comment`, or a
`workflow_dispatch` from CI) opens a new agent session on
Electric Cloud."
after: "Your software factory opens a new agent session on
Electric Cloud — a fresh GitHub issue, an
`issue_comment`, or a `workflow_dispatch` from CI."
Same triggers, same destination — the rewrite puts the SF frame
first and presents the trigger list as concrete examples of what an
SF dispatches. The rest of the body (notification → skim diff →
steering message → finish on laptop) is unchanged.
APP_PAGE_PLAN.md §3.5 ASCII mockup updated to lock the new body so
the next reader doesn't reintroduce the omission.
Phase 3 is now complete:
§3 three ways to use it ✓ copy + grid + strip
§3.5 scenarios ✓ copy + placeholder illos + SF named
§6 built for builders ✓ six-card grid
Phases 4 (§4 multi-device + §5 bundled Horton), 5 (asset capture),
and 6 (polish + redirects + build) remain.
Co-authored-by: Cursor <cursoragent@cursor.com>
Lands §4 and §5 of the /app rewrite, leaving only phase 5 (real
asset capture) and phase 6 (polish + redirects + build) before the
PR is ready for review.
§4 "Multi-device, multi-user." — title + 1-sentence subtitle frames
the page's positioning ("agents run on the server, not the client").
A 16/8 `<AdPlaceholder>` reserves the diagram slot (phase 5 swaps
it for an inline SVG matching `EntityOverviewDiagram.vue`); three
pillars below split the locked plan paragraph into orthogonal
points so it reads as scannable rather than a wall of prose:
· Same session, every device
· Shared with your team
· Pull-wake runners
Each pillar uses the §3-style brand-tinted icon chip (lucide
`monitor-smartphone`, `users`, `cpu`) — no second register of
icon styling needed.
§5 "Horton, in the box." — two-zone `:dark` Section that
intentionally breaks from the §3 / §3.5 / §6 card grids so the
page has visual variety as the reader scrolls:
Zone 1 — three capability pillars (provider · working directory ·
skills + slash), one each per locked plan sub-bullet.
Zone 2 — "Things you can ask Horton to do" 3-column prompt grid
(Chat / Code / Research) with every example wrapped in
`<code>` and styled as a rounded brand-tinted chip so
the visual reads as a prompt library rather than another
feature grid.
Pillar icons (lucide): `key-round`, `folder-tree`, `wand-2`.
Ask-grid headers (lucide): `message-circle`, `braces`, `compass`.
Dashed hairline separates the two zones so the section still reads
as one continuous Horton pitch.
§5 "Pick your provider" body breaks the plan's "providers" list
into models (Anthropic, OpenAI, DeepSeek, Moonshot) and tools
(Brave Search, E2B) — the locked plan ASCII listed them all
together but conflating LLM providers with tool services would
have read as imprecise once the section is rendered.
Responsive: §4 pillars + §5 pillars + §5 ask-grid all collapse
3 → 2 → 1 alongside the existing §3 / §6 breakpoints, so the page
reflows together rather than at staggered widths.
Phase comment in code updated to mark §4 / §5 as phase 4 ✓ (§4
still owes its SVG diagram in phase 5).
Co-authored-by: Cursor <cursoragent@cursor.com>
Catches three issues in the phase 4 commit (4d39f30): §5 pillar 2 had an orphaned tools sentence that didn't fit under "Pick your working directory": before: "Horton reads and edits whatever you point it at — no per-project install. Bash, web search, fetch URL, spawn worker, send, skills: all in the bundled toolset." after: "Horton reads and edits whatever you point it at — no per-project install. The picker walks your filesystem; recent directories surface automatically." The tools list was content from the §5 ASCII's "Tools" block that I mis-wired into the working-directory pillar. The bundled toolset is already enumerated in §3 card 1 body ("Chat to a coding agent that can read, write, edit, run bash, search the web, fetch URLs, and spawn parallel workers"), so the page doesn't need a second enumeration here. The new pillar 2 second sentence keeps pillar heights balanced and stays on-theme. §5 pillar 3 had a marketing-fluff trailer I added beyond the plan: before: "...install your own skills to ship workflows to your team. Slash commands are first-class — discoverable, composable, shareable." after: "...install your own skills to ship reusable workflows to your team." The "first-class — discoverable, composable, shareable" line is the kind of category-label fluff the plan deliberately avoids. Plain "reusable workflows" carries the same meaning in one word. `.ad-multi-pillars` CSS block comment claimed the §4 pillar icons use "the same brand-tinted square icon chip as §3 modes". They share the visual pattern (brand-tinted square chip, same tint formula) but render slightly smaller (40px/10px-radius vs §3's 44px/12px-radius). The new comment names the shared pattern explicitly AND the deliberate size delta, plus the reason — §4 pillars carry one short paragraph each rather than §3 cards' four bullets, so the icon chip should defer to the body copy. APP_PAGE_PLAN.md §5 sub-bullets updated to lock the three new pillar bodies and add a "Provider-list rationale" paragraph explaining why pillar 1 splits the §5 ASCII's "Providers" block into models vs tools. Co-authored-by: Cursor <cursoragent@cursor.com>
…rt framing
Page-wide pass on the /app rewrite to address three issues raised in review:
incorrect copy, eyebrow inflation, and overall text density.
Factual corrections
- §3 card 1 + §5 pillar 3: reframe /quickstart as "learn Electric Agents
itself" — per packages/agents/skills/quickstart.md it walks the user
through building a multi-agent app on the SDK, not generic onboarding.
- §6 MCP card: "workspace mcp.json override" → "workspace mcp.json takes
precedence", matching the precedence-on-name-conflict behaviour in
packages/agents/src/server.ts.
Eyebrow cull (5 section + 3 card)
- Drop section eyebrows on §3 / §3.5 / §4 / §5 / §6 — each was a near-
restatement of the title below it. §7a "Desktop" stays (its title is
generic). The Section component already guards on $slots.eyebrow, so
removing the slot is a clean no-op.
- Drop the CODE LOCALLY / ATTACH REMOTELY / BUILD WITH THE SDK eyebrows
on the three §3 cards. Card titles ("Code with Horton, locally." etc.)
carry the categorisation on their own. Removes the .ad-modes-eyebrow
rule + element entirely.
Density / text trims
- §3 "You can:" lists trimmed from 4 → 3 bullets each. Card 2 lost the
"hand a session off to a teammate" bullet — that claim is the explicit
topic of §4 pillar 2 and didn't need restating here. Multi-user is
intentionally kept in §4 (it is a forward-looking platform feature).
- §3.5 scenario bodies lose one line each (parenthetical example, tile-
workspace clause that duplicates §6, "see what it found" clause).
- §5 pillar 1 drops "— keys never leave your machine" (tautological with
"stored in the OS keychain") and the internal SecretStore reference.
- §6 builders cards drop the dashed-divider "Use it to…" hint paragraph
on all six cards. The §3.5 scenarios already do the show-don't-spec
work; §6 reads as a spec sheet now, intentionally. Removes the
.ad-builders-hint rule.
Plan updates (APP_PAGE_PLAN.md)
- Lock new bodies + bullet lists for §3 cards.
- Lock trimmed §3.5 scenario bodies (one line each).
- Lock new §5 pillar bodies + add /quickstart framing rationale.
- Add a `Multi-user is a kept-forward claim` note under §4 so future
passes don't drop the multi-user-view language.
- Record removed eyebrows + removed §6 hints with rationale per section.
Net diff on AppDownloadPage.vue: +31 / -97 lines.
Co-authored-by: Cursor <cursoragent@cursor.com>
…lease notes Three small hero-row tweaks raised in review: - Add a thin vertical divider in the 28px gap between the desktop trio (macOS · Windows · Linux) and the mobile pair (iOS · Android) in the §1 platform glyph row. Pseudo-element on the iOS glyph (4th child), absolutely positioned at -14px so it sits centred in the column gap. Height ~22px matches the icon glyph so the line reads as part of the row rather than a section divider. - Shrink the `Preview` pill under the mobile pair: font-size 10px → 8px, padding 3px/10px → 1px/7px, letter-spacing 0.12em → 0.14em to keep the text readable at the smaller size. The pill is now visibly subordinate to the iOS/Android labels above it instead of competing with them. - Drop the `Release notes` link from the hero and put it under the §7a desktop download grid (between the cards and the Unsigned Preview aside) where it pairs naturally with the download CTAs. Rename `.ad-hero-meta` → `.ad-download-meta` to reflect the new home. Co-authored-by: Cursor <cursoragent@cursor.com>
Rework the hero so the product name leads instead of the verb-chain: - Add a small mono strap (`run · observe · steer`) above the H1. - Promote the H1 to `Electric Agents App.` with `App` as the brand- accented word so the page clearly names the product the user is looking at. - Trim the sub: drop `for the Electric Agents platform` (the new H1 makes that clause redundant). Reads `Desktop and mobile clients — one app to code with Horton, attach to remote sessions, and build your own agents on the infra and SDK.` The strap-H1-sub triad now reads action → product → details with the H1 dominating, which is closer to the rest of the site's branding rhythm. Co-authored-by: Cursor <cursoragent@cursor.com>
- §7a: drop the `Desktop` eyebrow and change the title from
`Choose your platform` to `Desktop App`. The eyebrow was a near-
repeat of the title and the title is now consistent with §7b's
`Native iOS & Android App` framing.
- §7b eyebrow: `Mobile · Preview` → just `Preview`. The new title
carries the "Mobile" word.
- §7b title: `Native iOS & Android` → `Native iOS & Android App`.
- §7b layout rethink: the old single-row card with body+CTA sat at
max-width 920px with no horizontal centering, so it landed
left-aligned on a wide dark section with a big empty right half —
orphaned between §7a's full-width grid above and §7c's full-width
canary list below. Rebuilt as a centred two-column strap:
• Phone-shaped `AdPlaceholder` (9:16) on the left at ~280px wide
• Body + `View on GitHub →` CTA on the right
• Both centred under the section header (max-width 920px,
`margin: 0 auto`)
Drops the card chrome (border + bg) since the placeholder's own
dashed border + caption now carry the visual. Mirrors the §2
visual-strap rhythm (placeholder + caption) rather than the §7a
download-grid rhythm. Phase 5 swaps `mobile-app-preview.png` for
a real iOS screenshot.
Responsive: at <=768px the two columns stack, placeholder caps at
240px and centres above the text.
Co-authored-by: Cursor <cursoragent@cursor.com>
…s each)
The 'Three ways to use it' section read as too text-heavy relative to
the rest of the page (long paragraphs + long bullets stacked in three
cards). Trimmed to roughly half the previous word count, structure
unchanged:
- Card bodies cut by ~45% each:
- Card 1: drop the 5-model enumeration (it's already in §5 pillar 1).
- Card 2: drop the 'your team's' middle clause + the device-handoff
sentence (the bullets show that, and §4 covers multi-device).
- Card 3: trim the 7-feature enumeration to 3 (§6 builder grid
expands on the rest).
- Bullets: 3 long-form bullets → 4 short one-line bullets per card.
Each bullet now fits roughly one line at the card width, so the
cards scan as a feature comparison rather than a wall of prose.
Total bullets 9 → 12, total bullet text shorter overall.
The result: card heights are well-balanced, vertical space ~halved,
and the 'You can:' labels still align across the three cards (the
existing `margin: auto 0 8px` keeps that working with the new
shorter content).
Plan doc updated to lock the new bodies + bullets and record the
trimming rationale per card.
Co-authored-by: Cursor <cursoragent@cursor.com>
Matches the `/agents` hero convention (`Electric <Agents>` — no trailing punctuation). Avoids a non-accented `.` floating after the cyan `App` brand word. Plan doc updated to lock in the finished hero shape: strap + brand-name H1 + accented `App` + no period. Co-authored-by: Cursor <cursoragent@cursor.com>
The `Preview` pill was anchored to cols 4-5 under the iOS + Android cluster which left the bottom row visually loaded on the right with nothing on the left. Span the pill across all 5 columns and centre it; rename to `Mobile preview` so the meaning stays explicit now that the pill isn't directly below the mobile pair. The muted icon colour on iOS/Android still signals which platforms are in preview, and the vertical divider still anchors the desktop/mobile split. Co-authored-by: Cursor <cursoragent@cursor.com>
Two changes to the hero, both about lightening it: - Drop the `run · observe · steer` strap above the H1. The product name (`Electric Agents App`) is the headline; the strap added a beat without a payoff. Remove the matching `.ad-hero-strap` CSS. - Replace the single centred `Mobile preview` pill with a small `Preview` chip tucked under each of the iOS and Android labels. The badge now reads as a per-platform title-style mark — paired symmetrically on the right two glyphs — instead of one anchor pill that pulled the row's visual weight to one side. Co-authored-by: Cursor <cursoragent@cursor.com>
Reframe the trailing clause of the hero paragraph from a generic `on the infra and SDK` to a named cross-link: `on Electric Agents` pointing at the Agents landing page. Makes the relationship between the app and the platform explicit and gives a first concrete entry point above the fold. Add a small inline-link style scoped to `.ad-hero-text a` so the link reads as cyan-with-underline against the muted body copy — the global VitePress default flattens to the surrounding text colour in this context. Co-authored-by: Cursor <cursoragent@cursor.com>
Other landing pages (`agents-home`, `streams-home`, `sync-home`, `cloud-home`, `home`) all render their `<template #title>` slots without trailing periods. The `/app` page was carrying periods on 5 H2 section titles + 6 H3 sub-titles, which read as inconsistent chrome when read alongside the rest of the site. Strip the periods from: - §3-§6 H2s: `Three ways to use it`, `What this looks like in practice`, `Multi-device, multi-user`, `Horton, in the box`, `Built for builders`. - §3 mode cards (H3): `Code with Horton, locally`, `Attach to remote sessions`, `Build your own agents`. - §5 Horton pillars (H3): `Pick your provider`, `Pick your working directory`, `Skills + slash commands`. Subtitles, bullet text and body copy keep their proper sentence punctuation. Plan doc updated with an explicit heading-convention note so future edits don't reintroduce the inconsistency. Co-authored-by: Cursor <cursoragent@cursor.com>
Two paired tweaks to the hero platform row: - Preview chip: drop font-size from 8px to 7px, padding from 1px/6px to 0/5px, margin-top from 4px to 2px. The chip now reads as small punctuation under each mobile label rather than a second mark competing with the icon. - Cluster divider: lift from a fixed 22px tall hairline that only spanned the icon to a top:0 + bottom:20px line stretching from the iOS icon top to the iOS label bottom. The line now matches the height of the desktop column's visible content (icon + label) and clears the small chip that hangs below. Co-authored-by: Cursor <cursoragent@cursor.com>
The chip was already 7px but it still sat ~6px under the label because the parent glyph uses `gap: 6px` between its flex children, which dominated any margin on the chip. Pull the chip back into the gap with `margin-top: -5px` so it sits ~1px under the label baseline instead. Tighten the label's own line-height to 1 so the chip rides directly under the visible label glyph, not under the line-box. Re-tune the desktop/mobile divider's `bottom` from 20px to 13px to match the new (shorter) badge-area height under the iOS label, so the divider still ends at the desktop column's label-bottom. Co-authored-by: Cursor <cursoragent@cursor.com>
Previous tightening (-5px → 1px effective gap) sat the chip almost directly on the label baseline. Loosen to -3px so the chip sits ~3px under the label — still tight, but with enough breathing room to read as a separate badge rather than label punctuation. Bump the cluster divider's `bottom` from 13px to 15px to follow the chip down. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Plans an HTML/CSS mockup kit (responsive primitives + page-slot scenes) that replaces the §2 desktop-hero / mobile-hero AdPlaceholder pair on AppDownloadPage.vue with animated, OS-aware, theme-respecting scenes. Architecture is primitives + scenes with CSS @container reflow so future scenes (modes thumbs, scenarios, mobile session list, OG images) drop in without touching primitives. Single PR, eight phases internally; only phase 8 touches AppDownloadPage.vue. Co-authored-by: Cursor <cursoragent@cursor.com>
Phase 1 of the desktop+mobile mockup kit (APP_DESKTOP_MOCKUP_PLAN.md).
Lands the framework wiring no scene depends on but everything builds
on top of:
- website/src/components/brand-toys/app/tokens.css — rescoped copy
of agents-server-ui's --ds-* token sheet, gated by .app-mockup-root
+ data-theme so each mockup carries its own light/dark
independently of the brand-toys harness's forced html.dark.
- app/shared.css — utility baseline (font, body bg, mono helper).
- app/fixtures.ts — single source of truth for the fake content
primitives + scenes will render (sidebar tree, chat string, state
table rows + deterministic pulse order).
- app-download/useDetectedOs.ts — Vue composable that returns
'macos' | 'windows' | 'linux' so future scenes can paint the
visitor's own window chrome. Keeps the detection logic out of the
mockup tree so it's reusable from AppDownloadPage.vue too.
- brand-toys: register 'app' as a new ToyGroup (chip color, label,
GROUP_ORDER slot) + ship the throwaway app-tokens-probe toy that
renders the working palette as a swatch grid. Used as the phase 1
end-of-phase smoke test; will likely retire once the chrome
primitives land.
Verified: vitepress build passes; /brand-toys?id=app-tokens-probe
renders swatches that switch between dark navy + accent teal and
warm-stone + navy ink as theme is toggled, while html.dark stays
fixed by the harness.
Co-authored-by: Cursor <cursoragent@cursor.com>
…ase 2)
Phase 2 of APP_DESKTOP_MOCKUP_PLAN.md. Lands the three chrome
primitives every desktop scene composes from, plus their brand-toys
adapters:
- app/primitives/chrome/AppTrafficLights.vue — three 12px dots,
real macOS colours (#ff5f57 / #febc2e / #28c840), glyphs (× − +)
revealed in hover/active state. Pure CSS, no SVG.
- app/primitives/chrome/AppTitlebar.vue — OS-aware band. macOS
variant: 28px tall, traffic lights left, optional centred title.
Windows/Linux variant: 34px, inlined Electric icon-mark (teal in
dark / navy in light, matching DesktopTitleBar.module.css's
`:global(html[data-theme='dark']) .appIcon` rule), File/Edit/
View/Window/Help menu strip, drag region, min/max/close glyph
buttons drawn with currentColor pseudo-elements (mirroring
DesktopTitleBar.module.css). `mode="compact"` strips menu +
window controls for narrow-container variants.
- app/primitives/chrome/AppWindowFrame.vue — outer rounded shell.
Border-radius per OS (10px macOS / 8px Win / 6px Linux), single
--ds-divider hairline, --ds-shadow-3 drop. Two slots
(titlebar + body) so scenes compose chrome + workspace cleanly.
overflow:hidden so slotted titlebar bg clips to corners.
Toys exposed in /brand-toys (`app-traffic-lights`, `app-titlebar`,
`app-window-frame`) with 'auto' OS resolution via useDetectedOs() so
visitors preview their own platform's chrome by default; explicit
macos|windows|linux force a fixed variant for screenshots.
Architecture decision: primitives stay pure (no `.app-mockup-root`
wrapper, no shared.css import). Each toy gets a tiny 5-prop
*Toy.vue wrapper in app/toys/ that handles the cascade + auto
resolution. Scenes will follow the same wrapping pattern in phase 5.
Verified live in browser: all three OS variants render correctly in
both themes, glyphs draw, drop shadows ground correctly, dark-mode
icon flips to accent teal.
Co-authored-by: Cursor <cursoragent@cursor.com>
Builds the sidebar primitives planned in APP_DESKTOP_MOCKUP_PLAN.md §6 (phase 3) so the upcoming hero / mobile scenes have a fixture-driven sidebar to compose with the chrome primitives from phase 2. - AppSidebarRow.vue — single entity row mirroring SidebarRow.tsx geometry (22-px icon column, status dot, title, type chip, +N count, expanded chevron, depth indent, selected/stopped variants). - AppSidebar.vue — full sidebar: optional 44-px header spacer, "New session" affordance with ⌘N kbd hint, section header, fixture-driven entity tree with per-row connector lines (trunk + horizontal stub + L-curve at last child) drawn via :deep ::before/::after pseudos matching SidebarRow.module.css. - AppSidebarRowToy.vue / AppSidebarToy.vue — brand-toys wrappers that apply .app-mockup-root + data-theme, exposing every variant axis. - Registers `app-sidebar-row` and `app-sidebar` in toys.ts so they show up in /brand-toys under the "App" group. Verified: vitepress build green; both toys render in dark + light themes with connector lines, depth indents, status dots and chevron behaviour matching the live agents-server-ui sidebar. Co-authored-by: Cursor <cursoragent@cursor.com>
Lands the animated content primitives planned in APP_DESKTOP_MOCKUP_PLAN.md §6 (phase 4) so the upcoming hero scene has the chat-tile and state-explorer pieces ready to compose. Chat primitives: - AppMessageBubble.vue — user-message bubble (input-bg fill, hairline border, soft shadow, meta row aligned to body column). - AppMessageInput.vue — composer slab (raised surface, send button, attach + model chips, ⌘↵ kbd hint). - AppAgentResponse.vue — the animated centrepiece. Walks through the CHAT_FIXTURE string at `cps` chars/sec via RAF, splits into pre / fenced-code / post segments, renders inline-code chips in the paragraphs, blinking caret tracks the cursor across segments, and the tool-call pill fades in once progress crosses appearAt (~0.55). Loop: stream → hold 3 s on completed → snap to 0 → repeat. RAF start is gated on IntersectionObserver so off-screen toys don't burn CPU, and prefers-reduced-motion snaps to end-state. State primitives: - AppStateRow.vue — single key/value/source row with kind-coloured left edge (message=blue, event=cyan, tool-call=amber, tool-result=green, error=red) and a 600 ms pulse keyframe. - AppStateTable.vue — full grid with deterministic pulse loop walking STATE_PULSE_ORDER at `pulseRate` Hz. Same observer + reduced-motion gating. Workspace primitives: - AppTileShell.vue — tile chrome (column flex, --ds-bg, shared --chat-col-width / --chat-surface-width geometry on the body). - AppTileHeader.vue — 44-px header strip with status pip, mono title, action dots. - workspace/parts/ChatTileContent.vue — composes header + bubble + agent response + composer with chat-surface mask + density toggle. - workspace/parts/StateTileContent.vue — header + state table. Toy wrappers (8 entries under group=app): - app-message-bubble, app-message-input, app-agent-response, app-state-row, app-state-table, app-tile-shell, app-chat-tile-content, app-state-tile-content. The agent-response and chat-tile toys expose a `progress` slider (-1 = auto / RAF driver, 0..1 = manual scrub) for screenshot framing. Verified: vitepress build green; agent-response renders inline code chips, fenced ts code-slab, caret tracking, and tool-call pill at progress=0.95; state-table pulse loop confirmed via CDP DOM read (rows toggle data-pulse on the cycle). Co-authored-by: Cursor <cursoragent@cursor.com>
Reverts the wrapper-level `transform: scale(0.8)` that shrunk the desktop's on-page footprint and replaces it with an inner sizing wrapper sized at 125 % that is scaled back down by 0.8. Net result: - Visible footprint of the desktop is back to its original 86 % of the stage — same on-page size as before any scaling work. - The scene inside renders at 125 % intrinsic resolution, so every UI element (sidebar rows, tile headers, message text, state inspector rows, composer, footer…) lands on screen at 80 % of its native size. Same window size, finer detail per pixel. - The scene's `@container` queries now fire at the larger intrinsic width (~107 % of the stage), keeping the sidebar + state tile visible at any reasonable hero width. Also fixes the sidebar footer being clipped by the workspace's `overflow: hidden`. The `.sidebar` had `flex-shrink: 0` which made it claim the parent's full height even when a 44-px titlebar-controls row was its sibling above — overflowing by exactly 44 px and pushing the footer below the visible area. Drops `flex-shrink: 0` and adds `min-height: 0` so the flex algorithm can shrink the sidebar to fit the available column height; the standalone toy still gets `height: 100 %` block sizing because its parent isn't a flex container. Co-authored-by: Cursor <cursoragent@cursor.com>
Replaces the four scenario-card placeholders with focused, animated
mockups that demonstrate each scenario's concept:
1. GitHub issue → triage on phone → finish on desk
→ sidebar + chat. Default sidebar fixture (with the streaming
horton session at top) reads as "fresh CI session"; chat
title reframed as a GitHub issue id.
2. Local refactor with parallel workers
→ sidebar + chat with the parallel-rename parent selected so
the eye lands on the worker tree expanded under it.
3. Build an agent on the SDK, debug without redeploy
→ state-inspector-only. State tile is the leftmost surface
so the macOS chrome inset auto-routes to its header.
4. Cron-triggered overnight pipeline
→ chat-only, paused at progress=1 so the read is "morning
catch-up on a completed run" rather than a live stream.
Plumbing for this:
- HeroChatStateScene now takes `showSidebar` / `showChatTile` /
`showStateTile` visibility props plus a `responsive` flag. When
`responsive` is false the container queries are bypassed and the
visibility props decide the layout regardless of width — needed
because the scenario cards render at ~580 px wide, well below
the responsive breakpoints.
The macOS traffic-light chrome inset auto-routes to whichever
tile is leftmost when sidebar (and any earlier tile) is hidden.
- StateTileContent now accepts `chromeInsetTarget` so the scene
can route the inset to it the same way it does for chat.
- New `AppMockupEmbed.vue` wrapper centralises the inner-scale
rendering trick (render scene at 1/scale × intrinsic, scale
visually back to fit) so the scenario cards don't repeat the
CSS the hero already used.
Co-authored-by: Cursor <cursoragent@cursor.com>
Refactored fixtures.ts to support named variants (CHAT_FIXTURES,
STATE_FIXTURES) and threaded chatFixtureKey / stateFixtureKey down
through HeroChatStateScene → ChatTileContent / StateTileContent →
AppAgentResponse / AppStateInspector.
Each §3.5 scenario card and §3 modes card now picks the variant that
matches its narrative:
§3.5 — GitHub issue → CI spawns Horton:
chat fixture 'github-issue' (flaky auth test #1724 investigation)
§3.5 — Local refactor with parallel workers:
chat fixture 'parallel-workers' (fan-out rename across 4 packages,
matching the worker tree expanded in the sidebar)
§3.5 — Build an agent on the SDK, debug it without a redeploy:
state fixture 'summarizer' (custom entity with a failed
chunk-9 thread visible in records)
§3.5 — Cron-triggered overnight pipeline:
chat fixture 'overnight-research' (completed nightly scan with
412 sources, top 5 leads ranked by signal)
§3 — Build your own agents:
state fixture 'summarizer' (matches §3.5 #3 narrative)
Old constants kept as backward-compatible aliases so the brand-toy
stage and hero scene keep rendering the default fixture.
Co-authored-by: Cursor <cursoragent@cursor.com>
The §3 cards work better with their original lucide icon (code / radio / microscope) sitting above the title. The mockup embeds were forcing too much density into a card whose job is "name the three modes in one breath", and the scenario-tailored mockups in §3.5 already carry that visual weight where it belongs. §3.5 mockups (and the hero) are unchanged; only the §3 illos are reverted to the icon-only pattern. The .ad-modes-illo CSS rule that was added alongside the embeds is removed too. Co-authored-by: Cursor <cursoragent@cursor.com>
The three pillars above (provider · working directory · skills + slash) already say what Horton is, and the example-prompt grid was adding length without earning its space — the reader doesn't need a prompt library on the landing page. Removing it lets §5 read as one tight strip and tightens the hand-off into §6 "Built for builders". Removes the markup, the .ad-horton-ask* CSS rules, and the ad-horton-ask-grid entries in the responsive overrides; updates the section comment + the §5 CSS comment so they no longer reference the now-deleted Zone 2. Co-authored-by: Cursor <cursoragent@cursor.com>
Two related fixes to the chat surface:
1. Stick-to-bottom scrolling. The chat-surface was overflow:hidden
so streaming content slid off the bottom of the viewport once
the column outgrew the surface (visible in the §3.5 cards where
the surface is short). Real chat UIs always pin to the newest
content while the assistant streams; the mockup needs the same.
Switched .chat-surface to overflow-y:auto with the scrollbar
hidden (the soft bottom mask already conveys "more content
above"), and added a ResizeObserver on the inner .chat-column
that sets surface.scrollTop = surface.scrollHeight on each
growth event. First observation is skipped to avoid a tiny
visible jump on initial layout.
2. Tool-call card position. The card was rendering at the BOTTOM
of the response, after the post paragraph — it read as a
trailing receipt and got pushed further down as streaming
continued. Moved it to BETWEEN the pre paragraph and the code
block, where it reads as the natural rhythm "agent prepares
→ tool call → code result" (every default fixture's code
block IS the tool's result).
Made fixture.toolCall.appearAt optional and auto-derive it
from the segments — fires ~28 chars before the code block
reveals, so the entrance Transition can settle before the
code block fades in below. Dropped the per-fixture appearAt
overrides (0.55 / 0.5 / 0.4) since the auto-derived timing
is correct for all four fixtures.
Co-authored-by: Cursor <cursoragent@cursor.com>
Reframed the "Native iOS & Android App" section from a single
phone-screenshot strap into a layout that mirrors §7a desktop
downloads:
- Two-card grid: App Store (iOS · iPadOS) + Google Play (Android),
each carrying a small "Coming soon" badge in the head row and a
"Notify me — watch repo" CTA pointing at the GitHub repo. Same
visual tokens as `.ad-platform-card` so the page reads as one
coherent download section.
- A small hairline-bordered note beneath the grid points
developers at packages/agents-mobile so anyone willing to run
the Expo dev build can do so today (with a github icon to make
the "source repo" framing immediate).
Drops the AdPlaceholder phone-screenshot from the section — we'll
fold a real animated mobile mockup in alongside the hero mobile
slot in a later pass; until then the marketing-only screenshot
was reading as vapor.
Replaced the .ad-mobile-preview-* CSS with .ad-mobile-* (grid +
card + badge + repo-note) and added a `.ad-icon--github` class
for the repo note's leading icon.
Co-authored-by: Cursor <cursoragent@cursor.com>
Cuts the in-practice scenarios (§3.5) and multi-device pillar block (§4) wholesale, then folds the bundled-Horton config row (§5) and the builders dev-tooling row (§6) into a single 9-card "Everything in the box" feature grid. Three ways to use it (§3) is preserved as the headline framing and intentionally not folded in. Card layout: 3×3 → 2×3 → 1×9 alongside the rest of the page; tight spec-sheet rhythm (lucide icon + short title + one-sentence body). No mockups inside cards. Drops the now-unused AppMockupEmbed import and the .ad-scenarios-* / .ad-multi-* / .ad-horton-pillar-* / .ad-builders-* CSS in favour of one consolidated .ad-features-* block. Responsive overrides updated to match. Co-authored-by: Cursor <cursoragent@cursor.com>
Swaps the §3 "Three ways to use it" cards so the SDK / dev-tool framing
leads, Horton (the bundled coding agent) sits in the middle, and the
attach-remotely story closes. Bodies rewritten so they read as a
sequence:
1. Build — "The desktop is the dev tool for the entities *you*
write with the Electric Agents SDK…" (no longer opens with
"It's also the dev tool…")
2. Code — "Horton — our open-source coding agent — ships bundled
in the same app." (positions Horton as a bundled extra rather
than the headline)
3. Attach — "Wherever your agents run, attach to any
agents-server…" (ties the prior two cards together)
Strip beneath the grid updated to match: "build, code, and attach in
one app."
Co-authored-by: Cursor <cursoragent@cursor.com>
Drops the §4 features grid from 16 → 12 → 9 cards (3×3 at desktop widths). The headline card slots now hold: ▸ Build with the SDK custom agent types · state explorer · timeline ▸ Servers & sessions cloud or self-hosted · remote · MCP ▸ Configure & use provider · skills · phone Smaller details (working-directory picker, tile workspace, attachments, local discovery, CLI installer) move into an inline "Plus:" strip below the grid. The strip is unboxed — just a flowing paragraph with a mono eyebrow + mid-dot separators — so it reads as a footnote to the grid rather than a thirteenth row. Drops pull-wake runners entirely; not a fit for the page surface yet. Co-authored-by: Cursor <cursoragent@cursor.com>
Drops the heavy VitePress warning callout for the "Unsigned Preview" note and replaces it with the same dashed-hairline + icon-chip pattern used by §7b's "Want it sooner?" repo note — small shield-alert icon on the left, title + body + bullet list on the right. align-items is flex-start (vs centre on the repo note) since this block carries multi-line content. Moves the "Release notes" link from above the warning to below the signing note so it reads as the section's last word, with a lighter top margin to match. Co-authored-by: Cursor <cursoragent@cursor.com>
Adds a subtitle under the §3 "Three ways to use it" header that
enumerates the three modes inline ("Build your own agents on the SDK,
code locally with the bundled Horton, or attach to sessions running
anywhere on your servers."), so visitors get the framing before they
start scanning the cards.
Trims each card body to ~2-3 lines:
• Build — drop the inline package name
• Code — drop the second sentence's "files / parallel workers"
• Attach — drop the "your own / Electric Cloud" + "GitHub issues /
your software factory" enumerations
Bullets are unchanged; they already carry the concrete examples.
Co-authored-by: Cursor <cursoragent@cursor.com>
Switches the §4 "Plus:" inline list from a left-aligned flex layout to a centred text-flow paragraph, so it sits visually balanced beneath the 3×3 grid above. Replaces the leading-dot pseudo-separator (`+ ::before`) with a trailing-dot one (`:not(:last-child) ::after`). With the leading selector, when the list wrapped to a second line the wrapped item inherited an orphan dot at the start of the line; trailing dots stay attached to the previous item so wrapped lines start clean. Items now use `white-space: nowrap` so wrapping happens between items rather than inside a single name. Co-authored-by: Cursor <cursoragent@cursor.com>
Shortens the intro sentence so it fits on one line at desktop widths: "Signing is in progress, so macOS and Windows may ask for an extra confirmation on first open." (was 2 lines / ~22 words). Drops the bulleted UL in favour of two stacked .ad-signing-step paragraphs flush-left under the intro — no list-marker indent competing with the icon-chip column on the left. Co-authored-by: Cursor <cursoragent@cursor.com>
Replaces the placeholder phone in §1 with a real animated mobile mockup that mirrors the desktop session word-for-word. New pieces: - `useSharedHeroChatProgress` — singleton 0..1 progress ref + RAF driver. Both shadow-rooted scenes import the same module and feed the value into `AppAgentResponse` via `progress`, short-circuiting the per-instance internal RAF so they tick in lockstep. - `AppPhoneFrame` — generic phone bezel (9:19.5 aspect, uniform 1.7% bezel, dynamic island + home indicator). - `AppMobileTitleBar` — 1:1 port of `agents-mobile`'s `Header.tsx` in `align="center"` mode: chevron-back in accent11, centred 16/600 title, kebab MoreHorizontal trailing button. - `HeroMobileChatScene` — composes the phone frame + title bar + the same `AppMessageBubble`/`AppAgentResponse`/`AppMessageInput` primitives the desktop uses. Renders at a fixed 400-px intrinsic width and scales to fit via `transform: scale(calc(100cqw / 400px))` so the chrome reads at real iPhone proportions regardless of the wrapper size on the page. `HeroChatStateScene` gains a `shareProgress` prop so the App-page hero (and only the hero) opts into the shared driver — the brand-toys harness keeps the per-toy internal RAF so each instance can be scrubbed independently. Co-authored-by: Cursor <cursoragent@cursor.com>
Keeps the hero composition usable on small screens, highlights mobile preview paths for phone visitors, and syncs state explorer event streaming with the shared chat timeline. Co-authored-by: Cursor <cursoragent@cursor.com>
Removes repeated marketing phrasing, simplifies feature descriptions, and protects short phrases/product names with non-breaking spaces to avoid awkward wraps. Co-authored-by: Cursor <cursoragent@cursor.com>
✅ Deploy Preview for electric-next ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Resolve the pnpm lockfile conflict by regenerating from the updated workspace dependency graph. Co-authored-by: Cursor <cursoragent@cursor.com>
❌ 107 Tests Failed:
View the top 3 failed test(s) by shortest run time
View the full list of 16 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
Use a constant bezel inset and derive the screen radius from the outer phone radius so the curves stay concentric without over-rounding the corners. Co-authored-by: Cursor <cursoragent@cursor.com>
Electric Agents Mobile BuildLocal mobile checks ran for commit The EAS Android preview build was skipped because the |
Detect VitePress production stylesheet links emitted as rel="preload stylesheet" and clone them into the mockup shadow root as plain stylesheets so compiled scoped CSS applies outside dev mode. Co-authored-by: Cursor <cursoragent@cursor.com>
Use an explicit flex-wrapping layout for the feature grid plus strip so long items do not overflow in Safari. Co-authored-by: Cursor <cursoragent@cursor.com>
Apply Prettier wrapping to the app download page so format:check passes in CI. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the app page planning documents from the branch while keeping them available locally as untracked files. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the branch-only reference screenshot directory and clear the stale comment path that pointed at it. Co-authored-by: Cursor <cursoragent@cursor.com>
Preview
https://deploy-preview-4499--electric-next.netlify.app/app
Summary
/applanding page for Electric Agents Desktop and mobile preview downloads.Test plan
/app/locally in VitePress while iterating on desktop and mobile viewport layouts.Cannot find module 'vue'workspace warning inAppDownloadPage.vue.Made with Cursor