feat(#90): IMP-56 u1-u19 catch-up before final close (post-u20 push fix)
Some checks failed
Multi-MDX Regression (IMP-91) / multi-mdx-regression (push) Failing after 20s

u1: text_overrides axis in user_overrides_io
u2: structure_overrides axis in user_overrides_io
u3: vite allowlist for new endpoints
u4: text_override_resolver
u5: Step 12 text_overrides apply in phase_z2_pipeline
u6: structure_override_resolver
u7: text_path_stamper
u8: SlideCanvas text-edit capture
u9: SlideCanvas structure-edit overlay
u10: userOverridesApi service extension
u11: designAgent types extension
u12: slidePlanUtils restore
u13: user_overrides endpoint tests
u14: user_overrides restore tests
u15: pipeline fallback tests
u16: edit-mode state + gating tests
u17: slide_base print mode CSS
u18: /api/connect endpoint (vite)
u19: /api/export endpoint (vite)

Recovery scope: 29 files (12 modified + 17 new). u20 already pushed in
9439575; this commit lands u1-u19 that were authored but not committed
before #90 was externally closed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 06:12:13 +09:00
parent 943957562f
commit 4da22adb43
29 changed files with 4937 additions and 78 deletions

View File

@@ -75,6 +75,37 @@ export type ImageOverridesOverride = Record<string, ImageOverride>;
*/
export type ManualSectionAssignmentOverride = boolean;
/**
* IMP-56 #90 u10 — Step-22 text-edit persist axis. Keyed by `zone_id`; the
* inner mapping is `text_path` (= `{slot_key}.{line_index}`) → line value.
* The `text_path` stamp is emitted by `src/text_path_stamper.py` (u8) and
* applied at Step 13 (u9); the value is consumed by `text_override_resolver`
* (u4) and applied at Step 12 (u5). Stale paths (frame swap / layout
* regression between sessions) are tolerated by the backend resolver as
* `skipped`, NOT raised — so the on-disk axis is forward-compat with layout
* and frame churn. Mirrors Python `KNOWN_AXES` entry (u1) and Vite
* `KNOWN_USER_OVERRIDES_AXES` allowlist entry (u3).
*/
export type TextOverridesPerZone = Record<string, string>;
export type TextOverridesOverride = Record<string, TextOverridesPerZone>;
/**
* IMP-56 #90 u10 — Step-22 structure-edit persist axis. Keyed by `zone_id`;
* the inner mapping is SCOPE-LOCKED to `{slot_order, hidden_slots}` — slot
* reorder + slot hide only. Frame swap stays on the existing `frames` axis;
* the `structure_override_resolver` (u6) rejects frame-swap-shaped inner
* keys at the validate gate so Phase Z's no-AI-HTML-structure invariant
* holds across this persisted axis too. Per-slot `list[str]` line content
* is NEVER mutated by the u7 Step-12 apply — that is the `text_overrides`
* axis above. Mirrors Python `KNOWN_AXES` entry (u2) and Vite
* `KNOWN_USER_OVERRIDES_AXES` allowlist entry (u3).
*/
export type StructureOverridePerZone = {
slot_order?: string[];
hidden_slots?: string[];
};
export type StructureOverridesOverride = Record<string, StructureOverridePerZone>;
/** Full on-disk schema. All axes optional — file may carry any subset. */
export interface UserOverrides {
layout: string;
@@ -83,6 +114,8 @@ export interface UserOverrides {
zone_sections: ZoneSectionsOverride;
image_overrides: ImageOverridesOverride;
manual_section_assignment: ManualSectionAssignmentOverride;
text_overrides: TextOverridesOverride;
structure_overrides: StructureOverridesOverride;
}
/** Partial-mutation payload. `null` is the explicit clear sentinel (mirrors u4). */