mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-21 10:36:27 +03:00
Live: gate mid-generation source injection, monotonic bar, resumable disconnect
Three browser-side fixes for the same 3.5-to-4.0.1 regression. - Source-preview targets no longer source-inject per variant_progress checkpoint. Immediate injection raced framework (React/Vue) ownership and triggered removeChild errors, which surfaced as static previews. HMR now owns reconciliation while variants stream in; source injection runs only on the final done (its 750ms settle + retry ladder stays for non-HMR harnesses like Cursor). Progress counts still advance from the variant observer, and the svelte-component progressive path is unchanged. - The agent-phase progress bar advances monotonically. A behind/resumed checkpoint re-broadcasts an earlier phase (the server regresses the snapshot phase to generating), which moved the visible bar backward; a phase rank table now blocks a known-lower phase from overwriting a known-higher one. - The server-lost toast now frames the drop as resumable (session saved, reopen or restart live-poll.mjs) instead of "Session ended", which had led agents to rationalize bailing to direct edits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
dbe0c12b91
commit
2fa0e7d327
@@ -421,11 +421,30 @@ describe('live-browser source contracts', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('loads progressive source checkpoints through the no-HMR fallback', () => {
|
||||
it('does not source-inject per variant_progress checkpoint (HMR owns mid-generation reconciliation)', () => {
|
||||
// Isolate the variant_progress handler body.
|
||||
const progressCase = SOURCE.match(/case 'variant_progress':[\s\S]*?break;/);
|
||||
assert.ok(progressCase, 'variant_progress case should exist');
|
||||
assert.doesNotMatch(
|
||||
progressCase[0],
|
||||
/injectVariantsFromSource\(/,
|
||||
'source-mode progress must not source-inject per checkpoint; it races React/Vue ownership and triggers removeChild errors',
|
||||
);
|
||||
// The svelte-component progressive path stays.
|
||||
assert.match(
|
||||
SOURCE,
|
||||
/case 'variant_progress':[\s\S]{0,1400}?msg\.previewMode === 'source'[\s\S]{0,1000}?arrivedVariants >= targetArrived[\s\S]{0,260}?injectVariantsFromSource\(msg\.previewFile \|\| msg\.file, msg\.id\)/,
|
||||
'source-mode progress should let framework HMR settle before using the no-HMR fallback',
|
||||
progressCase[0],
|
||||
/injectSvelteComponentsFromManifest\(msg\.previewFile, msg\.id\)/,
|
||||
'component-preview progressive delivery must still stream per checkpoint',
|
||||
);
|
||||
});
|
||||
|
||||
it('source-injects only on the final done branch, keeping the 750ms settle', () => {
|
||||
const doneCase = SOURCE.match(/case 'done':[\s\S]*?break;\n {8}case /);
|
||||
assert.ok(doneCase, 'done case should exist');
|
||||
assert.match(
|
||||
doneCase[0],
|
||||
/setTimeout\([\s\S]{0,260}?injectVariantsFromSource\(msg\.file, msg\.id, \{ generationCompleted: true \}\)[\s\S]{0,40}?\}, 750\)/,
|
||||
'done should source-inject via the 750ms fallback for harnesses without HMR',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user