Skip to content

feat(studio): add Blocks panel for browsing registry blocks#697

Open
miguel-heygen wants to merge 73 commits into
nextfrom
feat/studio-blocks-panel
Open

feat(studio): add Blocks panel for browsing registry blocks#697
miguel-heygen wants to merge 73 commits into
nextfrom
feat/studio-blocks-panel

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

@miguel-heygen miguel-heygen commented May 9, 2026

Summary

Full Blocks panel for Studio — browse, search, add, drag-and-drop, live preview, and customize 52 registry blocks.

Phase 1: Browse & Add

  • 52 blocks from the registry, 5 categories: VFX (purple), Transitions (blue), Social (pink), Data (green), Scenes (amber)
  • Search bar with instant filtering by title/description
  • Category filter pills to narrow results
  • One-click Add — hover → click "Add" → block HTML copied to compositions/, preview refreshes

Phase 1b: Drag-and-Drop to Timeline

  • Block cards are draggable with styled ghost preview label
  • Drop on Timeline → copies block HTML, injects data-composition-src sub-composition at drop position
  • New TIMELINE_BLOCK_MIME type following existing TIMELINE_ASSET_MIME pattern

Phase 2: Live Previews

  • Animated thumbnails per block — actual composition renders in scaled iframes (1920px → 175px)
  • Hover preview tooltip — 500ms hover shows 400x225px enlarged preview above the card
  • Recently Used section — up to 6 recently added blocks shown as quick-access accent-colored pills

Phase 3: Block Parameters

  • BlockParam interfacecolor, text, number, select types with CSS variable mapping
  • Parameter controls — color pickers with hex display, range sliders, text inputs, select dropdowns
  • Params panel appears after adding a block that has defined parameters (6 blocks have params: Liquid Glass, Liquid Background, Portal, Chart, Logo Outro)
  • CSS variable injection deferred to follow-up (params currently log changes)

Files Changed

File Change
blockCatalog.ts BlockParam interface, params on 6 blocks
BlocksPanel.tsx Draggable cards, thumbnails, hover preview, recently used, params panel
BlockThumbnail.tsx New — iframe-based scaled live preview component
BlockParamsPanel.tsx New — type-aware parameter controls (color/number/text/select)
timelineAssetDrop.ts TIMELINE_BLOCK_MIME constant
Timeline.tsx onBlockDrop prop, block MIME handling
NLELayout.tsx onBlockDrop pass-through
App.tsx handleTimelineBlockDrop, handleAddBlock, blocks panel wiring
registry.ts /registry/blocks/:name/preview route for live thumbnails

Testing (agent-browser, Vite dev mode)

  • 52 blocks render with search + category filters
  • Live thumbnails load (iframe-scaled compositions)
  • Click-to-add writes block to compositions/, timeline updates with sub-composition structure
  • Params panel shows after adding block with params (Background color, Accent color, Speed slider)
  • Recently Used section populates after add
  • Drag start fires correct TIMELINE_BLOCK_MIME payload
  • Registry API serves block content and HTML preview
  • Zero console errors
  • Build passes (lint + format + typecheck + commitlint)

🤖 Generated with Claude Code

miguel-heygen and others added 30 commits May 4, 2026 14:41
* fix: stabilize studio preview and runtime sync

* fix: pass selector through timeline thumbnails

* feat: add studio timeline editing

* fix: disambiguate timeline edit targets

* fix: stop timeline auto-scroll in fit mode

* feat: use percentage-based timeline zoom

* fix: sync timeline playhead on zoom changes

* fix: reset timeline scroll when returning to fit

* feat(studio): add manual DOM editing inspector

* docs: update studio manual dom editing guide

* feat(studio): add image asset picker for fills

* feat(studio): add inline image uploads for fills

* fix(studio): use real file input for image fill uploads

* fix(studio): restore toast plumbing after rebase

* fix(studio): explain in-app upload limitation

* fix(studio): reuse asset-tab upload pattern in fills

* feat(studio): refine manual design inspector

* fix(studio): polish manual design inspector

* fix(studio): keep color picker in viewport

* fix(studio): clarify color picker selection

* docs: update manual DOM editing guide

* fix(studio): keep gradient color picker open

* fix(studio): scope text color to text layers

* fix(studio): add agent fallback for immovable layers

* fix(studio): address manual editing review feedback

* fix(studio): make local font selection reliable
Studio manual editing and timeline editing mutate project files directly, but those edits had no reliable undo/redo path. Before releasing manual editing, users need a way to recover from visual property changes, source-editor saves, timeline moves/resizes/deletes, and timeline asset drops.

The history also needs to survive a page refresh. A refresh should not erase the only way back from a bad manual edit.

- Adds a persistent per-project edit-history model for file snapshots.
- Stores undo/redo stacks in IndexedDB so history survives Studio refreshes.
- Records source editor saves, manual DOM edits, and timeline mutations.
- Adds toolbar undo/redo buttons with standard keyboard shortcuts: `Cmd/Ctrl+Z`, `Cmd/Ctrl+Shift+Z`, and `Ctrl+Y`.
- Validates current file hashes before applying undo/redo so external file changes do not silently overwrite newer content.
- Keeps history available in memory if IndexedDB persistence fails during a session.
- Adds focused unit coverage for the pure history model, storage adapter, controller/hook behavior, and project-file save helper.

Studio previously treated every editor mutation as an immediate file write. Manual DOM editing, timeline updates, and source-editor saves each had separate write paths, so there was no common transaction boundary where Studio could capture the file contents before and after an edit.

Undo/redo needed to sit above those write paths as a file-level transaction system: capture changed files before saving, write the new contents, persist the history entry by project, then apply undo/redo only when the current file content still matches the expected snapshot.

- `bun --filter @hyperframes/studio test src/utils/editHistory.test.ts src/utils/editHistoryStorage.test.ts src/hooks/usePersistentEditHistory.test.ts src/utils/studioFileHistory.test.ts` -> 4 files pass, 15 tests pass
- `bun --filter @hyperframes/studio test` -> 26 files pass, 289 tests pass
- `bun --filter @hyperframes/studio typecheck`
- `bunx oxlint packages/studio/src/App.tsx packages/studio/src/icons/SystemIcons.tsx packages/studio/src/hooks/usePersistentEditHistory.ts packages/studio/src/hooks/usePersistentEditHistory.test.ts packages/studio/src/utils/editHistory.ts packages/studio/src/utils/editHistory.test.ts packages/studio/src/utils/editHistoryStorage.ts packages/studio/src/utils/editHistoryStorage.test.ts packages/studio/src/utils/studioFileHistory.ts packages/studio/src/utils/studioFileHistory.test.ts` -> 0 warnings, 0 errors
- `bunx oxfmt --check packages/studio/src/App.tsx packages/studio/src/icons/SystemIcons.tsx packages/studio/src/hooks/usePersistentEditHistory.ts packages/studio/src/hooks/usePersistentEditHistory.test.ts packages/studio/src/utils/editHistory.ts packages/studio/src/utils/editHistory.test.ts packages/studio/src/utils/editHistoryStorage.ts packages/studio/src/utils/editHistoryStorage.test.ts packages/studio/src/utils/studioFileHistory.ts packages/studio/src/utils/studioFileHistory.test.ts`
- `git diff --check`
- `bun run --filter @hyperframes/core build:hyperframes-runtime` before commit hook, because the clean worktree needed the ignored runtime-inline artifact for typecheck
- Lefthook pre-commit -> lint, format, typecheck pass
- Lefthook commit-msg -> commitlint pass

- Started Studio locally at `http://127.0.0.1:5190/#project/undo-redo-sample`.
- Used `agent-browser` to select a preview element in the Inspector and change `#hero-card` from `left: 220px` to `left: 260px`.
- Refreshed Studio and verified Undo stayed enabled.
- Clicked Undo and verified the project file returned to `left: 220px`; clicked Redo and verified the inline `left: 260px` returned.
- Used `agent-browser` to drag the `side-card` timeline clip, refreshed Studio, then verified Undo restored the previous timeline attributes and Redo reapplied the timeline move.
- Recorded the tested undo/redo flow with `agent-browser`: `qa-artifacts/studio-undo-redo-2026-04-28/studio-undo-redo-flow.webm`.

- Local screenshots and recordings are kept under `qa-artifacts/studio-undo-redo-2026-04-28/` and are intentionally not committed.
- The scratch Studio project used for browser proof is local-only under `packages/studio/data/projects/undo-redo-sample/` and is intentionally not committed.
- The PR intentionally excludes the earlier PRD/TDD planning notes under `docs/superpowers/`; those remain local-only per request.
Studio frame capture could fail for projects mounted outside the repo when the project id came from an encoded hash route. A project like `Notion Showcase` loaded as `#project/Notion%20Showcase`, but the capture URL encoded that already-encoded value again, producing `/api/projects/Notion%2520Showcase/...` and a 404.

While validating the fix by seeking through the preview, capture also diverged from the visible player for nested compositions because the thumbnail route sought raw timelines instead of the same player seek path used by Studio preview.

- Decodes project ids when reading Studio `#project/...` routes and centralizes project hash/API path construction.
- Keeps API URLs encoded exactly once, including project names with spaces, literal `%`, reserved characters, and unicode.
- Updates Studio thumbnail capture to prefer `window.__player.seek(t)` and only fall back to raw timeline seeking for standalone pages.
- Preserves explicit `t=0` thumbnail requests instead of falling back to `0.5` seconds.
- Adds preview-regression CI coverage for Studio routing, frame capture URL construction, thumbnail seeking, and core thumbnail seek parsing.

Studio treated the hash route segment as the canonical project id even when the browser had already percent-encoded it. `buildFrameCaptureUrl` then encoded that string again, so a decoded project directory name and the capture API path no longer matched.

The preview/capture mismatch was a separate seek-path issue: the visible Studio preview seeks through the HyperFrames player, which maps global time into nested composition time. The capture route bypassed that layer and paused all registered timelines at the same global time.

The zero-second capture case came from parsing `t` with a truthiness fallback, so `parseFloat("0") || 0.5` became `0.5`.

- `bun run --cwd packages/studio test -- vite.thumbnail.test.ts src/utils/projectRouting.test.ts src/utils/frameCapture.test.ts`
- `bun run --cwd packages/core test -- src/studio-api/routes/thumbnail.test.ts`
- `bunx oxfmt --check .github/workflows/preview-regression.yml packages/studio/vite.thumbnail.ts packages/studio/vite.thumbnail.test.ts packages/studio/vite.config.ts packages/studio/src/utils/projectRouting.ts packages/studio/src/utils/projectRouting.test.ts packages/studio/src/utils/frameCapture.ts packages/studio/src/App.tsx packages/core/src/studio-api/routes/thumbnail.ts packages/core/src/studio-api/routes/thumbnail.test.ts`
- `bunx oxlint .github/workflows/preview-regression.yml packages/studio/vite.thumbnail.ts packages/studio/vite.thumbnail.test.ts packages/studio/vite.config.ts packages/studio/src/utils/projectRouting.ts packages/studio/src/utils/projectRouting.test.ts packages/studio/src/utils/frameCapture.ts packages/studio/src/App.tsx packages/core/src/studio-api/routes/thumbnail.ts packages/core/src/studio-api/routes/thumbnail.test.ts`
- `bun run --cwd packages/studio typecheck`
- `bun run --cwd packages/core build:hyperframes-runtime`
- `bun run --cwd packages/core typecheck`
- `git diff --check`

Pre-commit also reran lint, format, and typecheck successfully for the committed files.

Using `agent-browser`, I mounted `/Users/miguel07code/Downloads/Notion Showcase` into Studio's project data and opened:

```text
http://127.0.0.1:5197/#project/Notion%20Showcase
```

Before the fix, Capture requested `/api/projects/Notion%2520Showcase/thumbnail/index.html?...` and Studio showed `Capture failed`.

After the fix, I sought the preview to `0s`, `2s`, `10s`, and `18s`, captured each frame, and compared the visible preview crop against the capture output. The capture URLs all used `Notion%20Showcase`, not `Notion%2520Showcase`, and no failure toast appeared.

Mean pixel diffs for preview vs capture were:

- `0s`: `0.0`
- `2s`: `0.8641`
- `10s`: `0.3496`
- `18s`: `0.2309`

The small non-zero diffs are raster/antialias-level differences after resizing the capture to the preview crop dimensions.

- Browser screenshots, comparison sheets, network logs, and the `agent-browser` recording are local-only under `qa-artifacts/capture-button/` and are not committed.
- The local Notion Showcase project mount is an ignored symlink under `packages/studio/data/projects/` and is not committed.
- Thumbnail cache versions were bumped so stale captures generated with the old seek behavior are not reused.
miguel-heygen and others added 25 commits May 9, 2026 03:27
…e-layers

feat: auto-open timeline clip layers
Three bugs found via automated e2e testing of the v0.6.0-alpha preview:

1. core: add missing package.json export specifiers for
   studio-api/manual-edits-render-script and
   studio-api/studio-motion-render-script — the alpha.3 npm publish
   failed because the studio build could not resolve these sub-paths.

2. cli: fix init --example creating empty projects — tsup leaves empty
   template directories in dist/ during the build, causing
   existsSync(templateDir) to return true and skip the remote fetch
   fallback. Now checks for index.html inside the dir instead.

3. engine: fix unhandled EPIPE crash in streaming encoder — ffmpeg
   stdin/stdout had no error handlers, so a write after the ffmpeg
   process exits throws an uncaught error that crashes the process.

Verified with 8 consecutive e2e iterations (424 test runs, 0 flaky).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…selector

Power-user audit fixes for the alpha studio:

- vite.config.ts: wrap thumbnail generation in try/catch so Puppeteer
  TimeoutError doesn't crash the entire vite dev server as an uncaught
  rejection. Close the page on error to prevent browser session leaks.

- manualEditingAvailability.ts: enable motion panel and manual canvas
  drag editing by default (were both false, undiscoverable without
  knowing the env vars).

- PropertyPanel.tsx: show "N elements selected" feedback when multiple
  elements are selected instead of the generic "Select an element"
  empty state.

- RenderQueue.tsx + App.tsx: add FPS selector (24/30/60) to the render
  export bar instead of hardcoding 30fps. Pass the user's choice
  through to startRender.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes and improvements based on power-user testing feedback:

1. Fix stale selection after style edits — handleDomStyleCommit now
   calls refreshDomEditSelectionFromPreview after persisting, matching
   every other commit handler. Without this, the PropertyPanel showed
   frozen computedStyles after color/radius/shadow edits, making it
   look like editing "didn't work." Also adds error handling around
   the persist call.

2. Add rotation field to the Design panel Layout section — reads the
   current rotation angle from the manual edit manifest and commits
   via the existing handleDomRotationCommit handler.

3. Enable motion panel by default — STUDIO_MOTION_PANEL_ENABLED now
   defaults to true so the Motion tab is discoverable without env vars.

4. Color controls only when element has color — fill color section now
   only shows when the element has an explicit non-transparent
   background-color. Text color shows only when the element has a
   color style. Prevents showing color pickers on elements where
   color edits have no visible effect.

5. Exclude canvas from selection — added "canvas" to
   DOM_LAYER_IGNORED_TAGS so canvas elements are not selectable in the
   preview or listed in the layer panel.

6. Multi-selection feedback — shows "N elements selected" with
   guidance instead of the generic empty state when multiple elements
   are selected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The shared Puppeteer browser pool in getSharedBrowser() could throw a
30s TimeoutError during launch. This error propagated as an uncaught
rejection and killed the vite process, even though generateThumbnail
had its own try/catch — the browser launch promise rejected outside
that scope. Now getSharedBrowser itself catches launch failures and
returns null, so thumbnails degrade gracefully instead of crashing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Motion panel stays opt-in via env var per product direction. Only
the Design panel is enabled by default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The seek/play/applyAfter wrapper functions in manualEdits.ts crashed
with "Cannot set property X which has only a getter" when the player
or timeline objects define seek/play as getter-only properties. This
prevented ALL manual edits (position, rotation, size) from persisting
to disk — the error thrown during applyCurrentStudioManualEditsToPreview
aborted the save queue.

Wrapped all three property assignments in try/catch so wrapping
gracefully degrades when the target object is non-configurable.

Verified: position edit (X=42px) now persists to
.hyperframes/studio-manual-edits.json and survives page refresh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: alpha preview e2e fixes — exports, init templates, EPIPE crash
…on-ux

feat(studio): simplify inspector selection UX
Compositions with external sub-compositions (like apple-presentation
with 7 slides) load child compositions via fetch(). The root GSAP
timeline is only bound after all external compositions finish loading,
but the TransportClock duration was only set during initial setup.

When bindRootTimelineIfAvailable runs after the external compositions
load, it captures the root timeline but never updates the clock.
player.getDuration() continues returning 0, so the player's probe
interval never fires the 'ready' event, and the Studio shows "Loading
composition" indefinitely.

Now bindRootTimelineIfAvailable updates clock.setDuration when the
root timeline is late-bound. Guarded with try/catch for the early call
site where clock is not yet initialized (temporal dead zone).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix(runtime): composition loading stuck indefinitely on multi-slide decks
Prevent users from selecting elements in the preview while the
composition is still loading (showing "Loading composition" overlay).
Selection and hover highlighting are suppressed until the player fires
the ready event.

Also reverts motion panel and manual drag editing defaults to false —
these were accidentally set to true during the PR #693 merge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Visual, color-coded block browser with 52 blocks across 5 categories
(VFX, Transitions, Social, Data, Scenes). Search, filter by category,
and one-click add to project compositions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
miguel-heygen and others added 2 commits May 10, 2026 21:02
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… and parameter controls

Phase 2: iframe-based live previews in block cards via new /registry/blocks/:name/preview
route, hover tooltip with 400x225 enlarged preview on 500ms delay, and recently-used
section tracking last 6 added blocks as quick-access pills.

Phase 3: BlockParam type system with color/text/number/select controls, BlockParamsPanel
component shown after adding parameterized blocks, and params defined on 6 blocks
(liquid-glass, liquid-background, portal, data-chart, logo-outro).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls left a comment

Choose a reason for hiding this comment

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

First review at 433c6a7b. CI is mostly "skipping" (Build, CLI smoke, Test, Typecheck, Lint, all windows) — the only run checks are WIP (pass). Required-checks coverage on this PR is effectively zero. Per Rule 5, that's a finding on its own.

Audited:

  • Diff exceeded the API's 20000-line cap; couldn't pull full diff. Audited via file list (274 files) + targeted reads of the key code files (BlocksPanel.tsx, BlockThumbnail.tsx, BlockParamsPanel.tsx, blockCatalog.ts).

Trusting:

  • evals/editframe/artifacts/devbox-2026-04-30/** (binary artifacts — read as "shouldn't be in this PR" not as code review)
  • docs/contributing/studio-manual-dom-editing.mdx (read structure only)
  • The 274-file diff in full

Blocker — --width is a literal file at the repo root

{"filename":"--width", "status":"added", "additions":0, "deletions":0, "changes":0}

gh api repos/heygen-com/hyperframes/contents/--width?ref=433c6a7b confirms there's a zero-byte file literally named --width at the repo root. This is from a stray mkdir --width or touch --width shell invocation where someone meant to pass --width as a flag and the shell parsed it as a positional arg. Should not ship — delete it before merge.

Blocker — eval artifacts (PNGs, MP4, WEBM, devbox reports) shipped in a feature PR

evals/editframe/artifacts/devbox-2026-04-30/** contains:

  • 4 browser-proof PNGs + 1 WEBM screen recording
  • 7+ snapshot PNGs (editframe-{1200,5000,8500,9400}ms.png, frame-00…05.png)
  • editframe/index.html, editframe/render-vp9.mjs (a 96-line VP9 render script)
  • HTML reports + JSON results

These are evaluation artifacts from a one-off comparison test, not source code for the Blocks panel feature this PR ships. They bloat the repo (PNGs/MP4 in git are forever) and have nothing to do with the feature in the PR title. Either move them to a separate "evals: editframe comparison" PR or to an out-of-tree artifact bucket (S3, GH release asset).

Blocker — base is next, not main; release-merge will widen the surface

baseRefName: "next". The PR targets the next branch, which presumably batches into main on a separate release cadence. That means the diff that lands on main is this + whatever else is on next at release time. The 274-file shape combined with no green required checks combined with the --width debris means a release-merge from next could ship anything in this surface area. Per Rule 8, this is the "human-approved-large-PR" failure mode — even if the Blocks-panel code is fine, the surrounding cruft sneaks in.

Recommend: clean up --width + evals artifacts before this lands on next, so the eventual next → main release has a clean surface.

Strengths (Blocks panel code, where I could read it)

  • TIMELINE_BLOCK_MIME follows the existing TIMELINE_ASSET_MIME pattern in timelineAssetDrop.ts. New constant alongside existing one, no fork of the convention. ✓
  • BlockParam interface (color/text/number/select) is a sensible four-type schema for the params panel. CSS variable mapping per param is the right shape for live updates.
  • BlockThumbnail.tsx (new component) for iframe-scaled live previews is the right factoring — keeps the heavy scaled-iframe logic out of BlocksPanel.tsx's render loop. Should be React.memo-wrapped (Rule 6) at the boundary where the parent's state changes faster than the thumbnail's props; I couldn't verify this without reading the full file but the import line in BlocksPanel.tsx looks named-export style which suggests it's a direct functional component — worth adding memo if not.
  • registry.ts adds /registry/blocks/:name/preview route for the live-iframe content — proper separation from the API surface.

Important — listener / timer cleanup audit (Rule 6) blocked by diff size

Can't audit BlocksPanel.tsx / BlockThumbnail.tsx / BlockParamsPanel.tsx for useEffect cleanup pairs (return functions matching addEventListener / setTimeout / MutationObserver) without reading the full file content. The hover-preview tooltip (500ms hover) implies a setTimeout that needs clearTimeout on unmount or hover-end; the iframe thumbnails imply a useEffect mount lifecycle that needs to clean up iframe.src = "about:blank" or remove the iframe before unmount or the browser keeps loading. If a hover starts and the user unmounts the panel mid-debounce, the timer fires against a stale ref. Highly recommend: include a grep -E "setTimeout|setInterval|addEventListener" packages/studio/src/components/blocks/ output in the PR description, with the matching cleanup site for each. Standard refactor-discipline ask per Rule 6.

Important — no test coverage for the new feature

Phase 1, 1b, 2, 3 are all called out as "tested in agent-browser, Vite dev mode." That's exploratory testing; no unit/component/E2E tests are added in the diff (file list shows 0 *.test.tsx for the new components). For a 29k-line feature, the long-term cost of zero test coverage is high — every future refactor of BlocksPanel/BlockThumbnail/BlockParamsPanel will be eyes-and-prayers.

Minimum bar: a couple of component tests for BlocksPanel.tsx (renders 52 blocks, search filter applies, category pill filters, "Add" button writes the block to disk). The drag-and-drop and live-preview iframe paths are E2E and can wait — but the synchronous render logic should have RTL coverage.

Important — .gitignore change to +2 lines is small but worth confirming

The .gitignore modification is +2/-0. Without diff access I can't see what's being ignored — verify it's not ignoring the eval artifacts that DID get committed (that'd be a sign the author intended to exclude them but the gitignore was added after the commit).

Nit

  • --width file aside, ensure the eval artifacts move to a separate location regardless of PR scope.
  • Phase 3 "params currently log changes" — note in the PR or block-catalog docs that the params controls are wired but don't actually apply yet. Otherwise an author who hits "Add" with params expects live application and gets a no-op.

Verdict

Verdict: REQUEST CHANGES
Reasoning: Three blockers: literal --width file at repo root (shell-flag-as-arg artifact), ~12+ MB of eval artifacts (PNGs/MP4/WEBM/reports) shipped inside a feature PR, and effectively zero required-check coverage (all skipped). The Blocks-panel code I could read looks well-factored, but the diff is too large for a one-pass audit and zero tests + zero CI makes that a real risk. Clean up the repo debris, split eval artifacts to their own location, and either land tests or split the feature into Phase-1 / Phase-1b / Phase-2 / Phase-3 sub-PRs.

— Vai

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.

2 participants