Skip to content

Add public homepage with live demo and auth-aware routing#31

Merged
hackerwins merged 14 commits into
mainfrom
homepage
Mar 14, 2026
Merged

Add public homepage with live demo and auth-aware routing#31
hackerwins merged 14 commits into
mainfrom
homepage

Conversation

@hackerwins

@hackerwins hackerwins commented Mar 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add a public-facing homepage at / with hero, live demo iframe, feature cards, developer API/CLI examples, open source CTA, and footer with theme toggle
  • ThemeProvider now supports ?theme= query param and postMessage for iframe theme sync
  • Homepage always renders at /; authenticated users see "Go to Workspace" CTA, unauthenticated see "Get Started"
  • Logout redirects to homepage instead of login page
  • Responsive layout for mobile viewports
  • Syntax highlighting for developer section code blocks (no external deps)

Test plan

  • Visit / while logged out — homepage renders with all sections
  • Visit / while logged in — homepage renders with "Go to Workspace" button
  • Click "Go to Workspace" — navigates to workspace
  • Click sidebar logo — navigates to homepage
  • Log out — redirects to homepage
  • Toggle theme in footer — page and iframe theme sync
  • Resize to mobile — nav links hidden, padding adjusted, layout responsive
  • Session expiry — redirects to /login (not homepage)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a public homepage landing page with navigation, hero section, live demo, features, developer guides, and open source information.
    • Added dark/light theme toggle in footer with external theme control via URL parameters.
    • Live demo section with real-time theme synchronization.
  • Authentication & Routing

    • Updated authentication flow to route unauthenticated users to the homepage instead of directly to workspaces.

hackerwins and others added 11 commits March 14, 2026 21:15
Defines the public-facing homepage for Wafflebase with hero,
live demo iframe, feature cards, developer section (REST API/CLI),
open source CTA, and footer with theme toggle.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
12-task plan covering theme infrastructure, routing,
6 section components, and final composition.
Also adds docs/specs/ as the spec location in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Allows external control of theme for iframe embedding.
Skips localStorage when theme is set via URL parameter.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Unauthenticated users see landing page at / with hero, live demo
iframe, feature cards, developer API/CLI examples, open source
CTA, and footer with theme toggle. Authenticated users redirect
to their workspace.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
REST API examples now show range queries, formula writes, and
batch updates with delete (null). CLI examples use actual
wafflebase command names with --formula, --format, and batch
via stdin.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Tokenizes shell code into comments, strings, flags, commands,
HTTP methods, and prompts with distinct colors. No external
dependencies — uses a simple line-based tokenizer.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Remove batch update and output format examples to keep
the code blocks concise and scannable.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Remove workspace redirect from HomeOrRedirect so the homepage
is always rendered at /. When logged in, "Get Started" buttons
change to "Go to Workspace" linking to the user's workspace.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Hide nav anchor links and footer links on small screens.
Reduce padding (px-4 on mobile, px-12 on md+), scale down
hero title and section spacing for narrow viewports.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@coderabbitai

coderabbitai Bot commented Mar 14, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@hackerwins has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 87f5432d-955d-4ba3-95f1-de0af7dd54be

📥 Commits

Reviewing files that changed from the base of the PR and between bc8f4e4 and 74b0270.

📒 Files selected for processing (5)
  • docs/specs/2026-03-14-homepage-plan.md
  • packages/frontend/src/app/home-or-redirect.tsx
  • packages/frontend/src/app/home/demo-section.tsx
  • packages/frontend/src/app/home/footer.tsx
  • packages/frontend/src/components/theme-provider.tsx
📝 Walkthrough

Walkthrough

Introduces a new public-facing homepage with seven section components, updates root routing to conditionally render the homepage or redirect authenticated users, enhances the theme provider to support external control via URL parameters and postMessage, and removes the legacy WorkspaceRedirect component.

Changes

Cohort / File(s) Summary
Homepage Components
packages/frontend/src/app/home/page.tsx, packages/frontend/src/app/home/nav-bar.tsx, packages/frontend/src/app/home/hero-section.tsx, packages/frontend/src/app/home/demo-section.tsx, packages/frontend/src/app/home/features-section.tsx, packages/frontend/src/app/home/developer-section.tsx, packages/frontend/src/app/home/opensource-section.tsx, packages/frontend/src/app/home/footer.tsx
Seven new React components compose a complete public homepage: NavBar with navigation links, HeroSection with CTAs, DemoSection with iframe and postMessage-based theme sync, FeaturesSection with grid layout, DeveloperSection with custom syntax highlighting, OpenSourceSection with badges, and Footer with theme toggle.
Routing & Authentication Flow
packages/frontend/src/App.tsx, packages/frontend/src/app/home-or-redirect.tsx, packages/frontend/src/app/workspaces/workspace-redirect.tsx
Replaces root route with HomeOrRedirect component that fetches current user and workspaces before conditionally rendering HomePage or redirecting authenticated users. Removes WorkspaceRedirect component entirely.
Authentication & Redirect Logic
packages/frontend/src/api/auth.ts
Refactors redirect mechanism from hardcoded redirectToLogin function to parameterized redirectTo(path: string) function, with logout redirecting to "/" and fetchWithAuth redirecting to "/login" on 401.
Theme Infrastructure
packages/frontend/src/components/theme-provider.tsx, packages/frontend/src/index.css
Enhances ThemeProvider to detect ?theme= URL parameter on mount, listen for external theme-change postMessage events, and conditionally skip localStorage writes when externallyControlled. Adds homepage-specific CSS color variables for light and dark modes: homepage-bg, homepage-hero-end, homepage-text, homepage-text-secondary, homepage-accent.
Documentation & Configuration
CLAUDE.md, docs/specs/2026-03-14-homepage-plan.md, .claude/settings.json
Added task workflow documentation for paired todo/lessons files, comprehensive homepage specification (763+ lines) detailing design, components, and implementation steps, and enabled superpowers plugin.

Sequence Diagrams

sequenceDiagram
    participant User
    participant Browser
    participant HomeOrRedirect as HomeOrRedirect
    participant AuthAPI as Auth API
    participant HomePage
    
    User->>Browser: Navigate to /
    Browser->>HomeOrRedirect: Render HomeOrRedirect
    HomeOrRedirect->>AuthAPI: fetchMeOptional (no retries)
    AuthAPI-->>HomeOrRedirect: User data | null
    alt User Authenticated
        HomeOrRedirect->>AuthAPI: fetchWorkspaces
        AuthAPI-->>HomeOrRedirect: Workspaces[]
        HomeOrRedirect->>HomeOrRedirect: Compute workspacePath from first workspace
        HomeOrRedirect->>HomePage: Render HomePage with workspacePath
        HomePage-->>Browser: Display homepage with workspace link
    else User Not Authenticated
        HomeOrRedirect->>HomePage: Render HomePage with workspacePath=null
        HomePage-->>Browser: Display homepage with "Get Started" link to /login
    end
Loading
sequenceDiagram
    participant Page as Page Load
    participant ThemeProvider
    participant URLParams as URL & Storage
    participant IFrame as Demo IFrame
    participant External as External Source
    
    Page->>ThemeProvider: Initialize
    ThemeProvider->>URLParams: Check ?theme= parameter
    alt ?theme= parameter present
        URLParams-->>ThemeProvider: theme value
        ThemeProvider->>ThemeProvider: Set externallyControlled=true
        ThemeProvider->>ThemeProvider: Use URL theme (skip localStorage)
    else No parameter
        ThemeProvider->>URLParams: Read from localStorage/default
    end
    
    ThemeProvider->>ThemeProvider: Setup postMessage listener
    
    External->>ThemeProvider: postMessage {type: "theme-change", theme}
    ThemeProvider->>ThemeProvider: Validate origin & update theme
    ThemeProvider->>IFrame: Send postMessage with new theme
    IFrame-->>ThemeProvider: Acknowledge
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 Hops with joy at the homepage grand,
Seven sections, a beautiful land!
NavBar, Hero, and Demo so bright,
Theme-switchers dancing in dark and light!
The rabbit says: "Welcome, all friends!" 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: adding a public homepage with live demo functionality and authentication-aware routing that handles both authenticated and unauthenticated users.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch homepage
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

@github-actions

github-actions Bot commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Verification: verify:self

Result: ✅ PASS in 96.3s

Lane Status Duration
sheet:build ✅ pass 13.3s
verify:fast ✅ pass 46.8s
frontend:build ✅ pass 13.9s
verify:frontend:chunks ✅ pass 0.3s
backend:build ✅ pass 4.6s
cli:build ✅ pass 1.6s
verify:entropy ✅ pass 15.4s
verify:browser ✅ pass 0.4s

Verification: verify:integration

Result: ✅ PASS

No longer needed since HomeOrRedirect replaced it at /.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

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

🧹 Nitpick comments (3)
packages/frontend/src/app/home/features-section.tsx (1)

44-49: Prefer feature over f in the list renderer.

Using a full name makes this block easier to scan and maintain.

♻️ Suggested change
-        {features.map((f) => (
-          <div key={f.title} className="bg-homepage-bg border border-homepage-accent/30 rounded-xl p-7">
-            <div className="text-3xl mb-3">{f.icon}</div>
-            <h3 className="text-lg font-semibold text-homepage-text mb-2">{f.title}</h3>
-            <p className="text-sm text-muted-foreground leading-relaxed">{f.description}</p>
+        {features.map((feature) => (
+          <div key={feature.title} className="bg-homepage-bg border border-homepage-accent/30 rounded-xl p-7">
+            <div className="text-3xl mb-3">{feature.icon}</div>
+            <h3 className="text-lg font-semibold text-homepage-text mb-2">{feature.title}</h3>
+            <p className="text-sm text-muted-foreground leading-relaxed">{feature.description}</p>
           </div>
         ))}
As per coding guidelines: "Use descriptive variable and function names that clearly convey intent and purpose".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/frontend/src/app/home/features-section.tsx` around lines 44 - 49,
The map callback currently uses a short, non-descriptive parameter `f` in the
features list renderer; rename it to `feature` in the `features.map(...)`
callback and update all uses inside the returned JSX (e.g.,
`key={feature.title}`, `{feature.icon}`, `{feature.title}`,
`{feature.description}`) so the code reads clearly and follows naming guidelines
while preserving existing behavior.
packages/frontend/src/app/home/opensource-section.tsx (1)

16-22: Use a descriptive map variable name instead of b.

This improves readability in the badge renderer.

♻️ Suggested change
-        {badges.map((b) => (
+        {badges.map((badge) => (
           <span
-            key={b}
+            key={badge}
             className="bg-homepage-bg border border-homepage-accent/30 rounded-lg px-6 py-3 text-sm text-homepage-text font-semibold"
           >
-            {b}
+            {badge}
           </span>
         ))}
As per coding guidelines: "Use descriptive variable and function names that clearly convey intent and purpose".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/frontend/src/app/home/opensource-section.tsx` around lines 16 - 22,
The map callback in badges.map currently uses a non-descriptive variable name
`b`; update the callback to use a descriptive name (e.g., `badge`) in the
badges.map call and inside the JSX span (the element rendering the badge) so the
purpose is clear—look for the badges.map(...) usage in the
OpenSourceSection/opensource-section component and replace occurrences of `b`
with `badge` (or another clear name) in the key, className usage, and the
rendered content.
packages/frontend/src/app/home/developer-section.tsx (1)

118-132: Consider memoizing the highlighted code blocks.

Since restApiCode and cliCode are static constants, highlightCode will produce identical output on every render. Consider using useMemo or computing the highlighted JSX once at module level to avoid redundant tokenization on re-renders.

♻️ Example: compute once at module level
+const highlightedRestApi = highlightCode(restApiCode);
+const highlightedCli = highlightCode(cliCode);

 export function DeveloperSection() {
   return (
     // ...
           <pre className="text-sm font-mono leading-7 whitespace-pre">
-            {highlightCode(restApiCode)}
+            {highlightedRestApi}
           </pre>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/frontend/src/app/home/developer-section.tsx` around lines 118 - 132,
highlightCode currently re-tokenizes static strings on every render; compute the
highlighted JSX once and reuse it by either calling highlightCode(restApiCode)
and highlightCode(cliCode) at module scope (e.g. highlightedRestApi /
highlightedCli constants) or by wrapping those calls in useMemo inside the
component (depend on []), then render those memoized values instead of calling
highlightCode directly; reference highlightCode, restApiCode and cliCode to
locate and replace the repeated calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/superpowers/specs/2026-03-14-homepage-design.md`:
- Around line 133-151: Update the spec to reflect the implemented routing:
instead of mandating a HomeOrRedirect component outside PrivateRoute that
redirects authenticated users from "/", document that the app currently renders
the homepage at "/" for both authenticated and unauthenticated users and adjusts
CTA state based on auth (useOptionalAuth / fetchMeOptional-driven UI
adaptation), and update the latency mitigation note to explain that
fetchMeOptional is used to avoid forced redirects and to allow the homepage to
render while auth state resolves (mention useOptionalAuth, fetchMeOptional,
PrivateRoute, and the CTA behavior on HomePage/LoadingSpinner/Navigate where
relevant).

In `@packages/frontend/src/app/home-or-redirect.tsx`:
- Around line 16-27: The homepage computes workspacePath too early while the
useQuery for workspaces (queryFn: fetchWorkspaces) is still unresolved, causing
a temporary null that can trigger a login CTA for an authenticated user; update
the logic that derives workspacePath (the const workspacePath) to only decide
between a real path or an explicit “no workspace” value after the workspaces
query has finished (use the query's isLoading or isFetching flag returned by
useQuery or check workspaces !== undefined) so that when user is truthy and
workspaces are still loading you neither return null nor show the login CTA;
reference useQuery, fetchWorkspaces, userLoading, Loader, and workspacePath when
making the change.

In `@packages/frontend/src/app/home/demo-section.tsx`:
- Line 4: Replace the hardcoded DEMO_TOKEN constant by reading it from an
environment variable (e.g., process.env.NEXT_PUBLIC_DEMO_TOKEN or
import.meta.env.VITE_DEMO_TOKEN depending on build system) inside the
demo-section module; update references to use the new token variable and add a
fail-fast check during module initialization or component mount that throws or
logs a clear error and prevents rendering when the env var is missing/empty so
token rotation and secret management are possible. Ensure the symbol DEMO_TOKEN
is removed and replaced consistently where used in demo-section.tsx and validate
the env var presence early.

In `@packages/frontend/src/app/home/footer.tsx`:
- Around line 15-17: The "Docs" and "API" anchor elements in
packages/frontend/src/app/home/footer.tsx (the <a> elements with innerText
"Docs" and "API") currently point to the same GitHub URL; update their href
attributes to the correct documentation and API reference URLs (or add a clear
TODO comment next to those <a> elements indicating the correct links to be
added) so they no longer duplicate the "GitHub" link (you can locate them by
searching for the anchors with className containing "hidden md:inline
text-stone-400" and innerText "Docs" and "API").

In `@packages/frontend/src/components/theme-provider.tsx`:
- Around line 36-45: The externallyControlled flag (created via useState in
ThemeProvider) is computed once from window.location.search and never updates,
causing URL-sourced themes to block future localStorage writes; fix by tracking
the source of theme changes instead: introduce a small source enum/state (e.g.,
'user' | 'external') or a boolean like isUserInitiated and update setThemeState
to accept/record the source, call setThemeState(..., 'external') when applying
theme from URL/postMessage and setThemeState(..., 'user') from UI interactions,
and only write to localStorage (using storageKey) when the source is 'user' so
user toggles persist while URL/postMessage origins do not prevent future
persistence.

---

Nitpick comments:
In `@packages/frontend/src/app/home/developer-section.tsx`:
- Around line 118-132: highlightCode currently re-tokenizes static strings on
every render; compute the highlighted JSX once and reuse it by either calling
highlightCode(restApiCode) and highlightCode(cliCode) at module scope (e.g.
highlightedRestApi / highlightedCli constants) or by wrapping those calls in
useMemo inside the component (depend on []), then render those memoized values
instead of calling highlightCode directly; reference highlightCode, restApiCode
and cliCode to locate and replace the repeated calls.

In `@packages/frontend/src/app/home/features-section.tsx`:
- Around line 44-49: The map callback currently uses a short, non-descriptive
parameter `f` in the features list renderer; rename it to `feature` in the
`features.map(...)` callback and update all uses inside the returned JSX (e.g.,
`key={feature.title}`, `{feature.icon}`, `{feature.title}`,
`{feature.description}`) so the code reads clearly and follows naming guidelines
while preserving existing behavior.

In `@packages/frontend/src/app/home/opensource-section.tsx`:
- Around line 16-22: The map callback in badges.map currently uses a
non-descriptive variable name `b`; update the callback to use a descriptive name
(e.g., `badge`) in the badges.map call and inside the JSX span (the element
rendering the badge) so the purpose is clear—look for the badges.map(...) usage
in the OpenSourceSection/opensource-section component and replace occurrences of
`b` with `badge` (or another clear name) in the key, className usage, and the
rendered content.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 048bf7cd-bd0f-49d1-ad6d-aa1b1368c689

📥 Commits

Reviewing files that changed from the base of the PR and between f70e9e3 and eee07e7.

📒 Files selected for processing (16)
  • CLAUDE.md
  • docs/specs/2026-03-14-homepage-plan.md
  • docs/superpowers/specs/2026-03-14-homepage-design.md
  • packages/frontend/src/App.tsx
  • packages/frontend/src/api/auth.ts
  • packages/frontend/src/app/home-or-redirect.tsx
  • packages/frontend/src/app/home/demo-section.tsx
  • packages/frontend/src/app/home/developer-section.tsx
  • packages/frontend/src/app/home/features-section.tsx
  • packages/frontend/src/app/home/footer.tsx
  • packages/frontend/src/app/home/hero-section.tsx
  • packages/frontend/src/app/home/nav-bar.tsx
  • packages/frontend/src/app/home/opensource-section.tsx
  • packages/frontend/src/app/home/page.tsx
  • packages/frontend/src/components/theme-provider.tsx
  • packages/frontend/src/index.css

Comment thread docs/superpowers/specs/2026-03-14-homepage-design.md Outdated
Comment thread packages/frontend/src/app/home-or-redirect.tsx Outdated
Comment thread packages/frontend/src/app/home/demo-section.tsx Outdated
Comment thread packages/frontend/src/app/home/footer.tsx Outdated
Comment thread packages/frontend/src/components/theme-provider.tsx Outdated
- Show loader while workspaces query resolves for authenticated users
- Use VITE_DEMO_SHARED_TOKEN env var for demo token with fallback
- Scope theme persistence skip to iframe context only (not entire session)
- Remove placeholder Docs/API footer links that pointed to GitHub

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@hackerwins hackerwins changed the title Add public homepage landing page Add public homepage with live demo and auth-aware routing Mar 14, 2026
@hackerwins
hackerwins merged commit b8d23f3 into main Mar 14, 2026
3 checks passed
@hackerwins
hackerwins deleted the homepage branch March 14, 2026 13:21
@coderabbitai coderabbitai Bot mentioned this pull request Apr 12, 2026
7 tasks
hackerwins added a commit that referenced this pull request Jun 3, 2026
* Slides: text-edit + adjust drag entry on grouped elements (#22, #31)

Two view-layer paths assumed `slide.elements` is flat:

- `enterEditMode` resolved the click target via
  `Array.prototype.find`, so double-click on text/shape elements
  nested inside a group silently no-op'd. Slide 22 of the
  Yorkie deck (text "웹/모바일..." in the right column) reproduced
  this — `Selection.doubleClick` drilled in correctly but the
  mount path bailed.

- `startAdjustmentDrag` used the same flat `find`, so the yellow
  adjustment diamond on a grouped shape armed but never wrote.
  Slide 31's Dogfooding pentagonArrow reproduced this.

The render-side mask for the editing element and the live
preview for adjustments had the matching flat `slide.elements.map`
bug — even if the entry paths were fixed in isolation, the
canvas would still ghost-paint the element under the in-place
editor / miss the live preview for grouped shapes.

Both paths now resolve elements via the existing recursive
helpers (`findElement`, `buildElementWorldLookup`) and pass
world-frame elements where downstream code expects world coords
(overlay text-box mount, world↔local adjustment conversion).
The store-side mutation APIs (`requireElement`,
`updateElementFrame`, `updateElementData`, `withTextElement`,
`withShapeText`) already walk the tree via `findElementPath`,
so the writes work transparently.

Live-verified on slide 22 (text edit enters at the correct
world position, no canvas ghost) and slide 31 (Dogfooding
arrow's adjustments commit after drag).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

* Slides: skip autofit-grow write when ancestor group is transformed

Code review caught a silent miswrite hole in the prior commit:
text-edit autofit-grow at commit time writes the editor-reported
content height (world / canvas-logical coords) straight into
`frame.h` via `store.updateElementFrame`, which expects LOCAL
coords. For top-level elements local === world; for groups with
rotation 0 + unit scale, w/h/rotation also match. But for a
rotated or non-unit-scale group, the world height would be stored
as local height, scrambling the element's frame.

Detect transformed ancestor by comparing local vs world frame
(w/h/rotation) at enter time and skip the autofit-grow write when
they diverge. Properly composing the inverse ancestor transform is
the right long-term fix, but until then this guard prevents the
silent corruption. Scope is unchanged: slide 22's groups have
rotation 0 + refSize === frame, so the autofit-grow path still
runs there.

Also annotate the todo's out-of-scope section with the matching
`startConnectorEndpointDrag` flat-find pattern (editor.ts:3135)
so future audits don't miss it. PPTX import can produce
connectors inside groups; the editor-side group op forbids it, so
the user-reachable failure mode is import-only — deferred.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
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