Two review findings:
- restoreSvelteMarkup visited an {#each} key with outer scopes only, so a
contract prop sharing a loop binding name rewrote the key: with prop
name -> user.name and loop context "name", the key (name.id) became
(user.name.id) in the accepted route. The key evaluates per item, so it
is now visited with the loop context and index bound. Regression test
verified failing on the previous code.
- enterLiveRoot silently kept the ambient working directory when the
resolved appRoot no longer existed or chdir failed, letting a helper
derive server, session, and source paths from the wrong project. Both
cases now exit with a clear error naming the app root and the --target
escape hatch.
AI-assisted (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Addresses two cursor review findings:
- {#each} bodies whose bound values appear in attributes (href={link.href},
src={item.img}) now record attr slots; the browser hydrates them from the
rendered attribute so component previews no longer mount with empty links.
Single-expression attributes hydrate exactly; mixed values stay unhydrated
as before. A new slot classifier also refuses shapes that would crash a
shallow hydration item (deep paths, method calls, bare item renders) and
routes them to source-preview mode instead.
- Style directives now run the mixed loop/outer identifier check before the
free-identifier param check, so style:width={base + r.pct} falls back
instead of minting a broken param.
Tests: attr-slot analysis units, crashy/lossy fallback units, an attribute-
bound anchor in the stateful SvelteKit fixture asserted through accept, and
a mountedDomProbe e2e hook that reads the hydrated href off the mounted
variant DOM (verified to fail when hydration is disabled).
AI-assisted (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
cursor[bot]: an expression mixing loop bindings with outer free names
(fmt(r.label) where fmt lives in the route script) was left verbatim, so
the detached preview referenced an undeclared identifier and failed at
mount, past the compile gate, because globals make it legal to the
compiler. Such expressions now mark the analysis unsupported and the
session takes source-preview mode. A globals allowlist makes Math/JSON
and friends count as neither free nor bound, which also fixes a latent
bug where a pure-global expression minted a nonsense prop.
Won't-fix on the same pass: the live-setup.md filename cross-reference
matches the repo's established reference-link convention.
This work was produced with AI assistance (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
cursor[bot]:
- style: directives with dynamic values now fall back to source-preview
instead of being scaffolded as boolean condition props that falsified
the style in the detached preview.
- class: directives carry a className probe, so v2 hydration answers the
condition from the live DOM instead of always defaulting to false.
- The existing-wrapper remount path now checks the mount result; a failed
remount keeps the error card instead of advancing to a CYCLING bar over
a page where nothing rendered.
greptile-apps[bot]:
- The repo-root live pointer records every booted app (most recent
first) and resolution prefers the app whose helper server is alive, so
a helper run from the repo root of a two-app monorepo can no longer be
redirected onto the wrong app's session store by the last boot. Legacy
single-value pointers still read.
This work was produced with AI assistance (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
A ground-up hardening of live mode, driven by a production session in a
nested-app monorepo that hit six distinct failure classes. Full design
rationale in docs/LIVE-REWRITE-PLAN.md; every Codex-reported failure now
has a mechanical fix and a regression test.
Roots: live/roots.mjs resolves appRoot/repoRoot/contextRoot once at boot
(keyed on dev-server configs, not monorepo brand markers), persists a
manifest, and every live CLI re-anchors onto it at startup, so a helper
run from the wrong directory can no longer fork session state. Context
files are discovered upward to the git root.
Render truth: variant_mounted / variant_mount_failed events give the
journal per-variant mount state; failures reach the agent's poll queue,
raise a persistent error card with Retry (no more localStorage wipe), and
an attach probe names root/dev-server mismatches explicitly. The browser
rehydrates from the server when localStorage is gone.
Svelte: the scaffolder now parses with the app's own svelte 5 compiler.
Control flow survives (an each collection crosses the contract as one
structured prop), keyed each blocks hydrate synthetic keys, and anything
a detached preview cannot support falls back to source-preview instead of
shipping a wrong scaffold. Preview modules live in per-publish revision
directories, defeating stale transform caches.
Accept: CSS is reconciled, not appended. Matching selectors are replaced,
params bake from params.json kinds, the compiler's unused-selector pass
prunes superseded rules (pre-existing dead rules protected), a selector-
loss postcondition refuses any write that would drop hand-written rules,
and live-complete refuses to finish while live plumbing remains in source.
Also: framework registry (live/frameworks/) with a crash-safe injection
journal, session-store snapshot caching with read-only reads, protocol
enum consolidation, steer Send button, honest DESIGN-panel empty states.
Testing: new unit suites (roots, AST scaffolder, accept CSS, accept
pipeline, framework conformance); e2e now fails on preview-tree 404s,
proves computed-style mount for every variant, drives the Tune panel
through baked params, and injects failures (broken mounts, republish,
storage loss). New runtime fixtures: monorepo-nested-vite (repo root !=
app root) and vite8-sveltekit-stateful (each blocks + state). Nightly
full-matrix cron. An independent adversarial review pass preceded this
commit; its blocker and major findings are fixed and regression-tested.
This work was produced with AI assistance (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>