diff --git a/docs/superpowers/specs/2026-03-13-script-library-pane-takeover-design.md b/docs/superpowers/specs/2026-03-13-script-library-pane-takeover-design.md index 553a35f2..9df9fc47 100644 --- a/docs/superpowers/specs/2026-03-13-script-library-pane-takeover-design.md +++ b/docs/superpowers/specs/2026-03-13-script-library-pane-takeover-design.md @@ -44,7 +44,7 @@ This is a cross-column relocation of the Generate/Download/Copy controls: ## New Work (not pre-existing) -The **Copy button in the action bar** is new — it does not exist in the current `ScriptGeneratorPanel`. It must be implemented as a new button in `ScriptConfigurePane` that copies `generatedScript` (or `displayScript` from `ScriptPreview`'s computation). Since `ScriptPreview` owns the substitution logic, the simplest approach is for the action-bar Copy to copy `generatedScript` from the store when available, and fall back to the draft preview via a shared utility or by co-locating the substitution logic. Implementation note: the action-bar Copy can duplicate `ScriptPreview`'s `handleCopy` behavior using `store.generatedScript` for the generated state; the draft substitution case is handled by `ScriptPreview`'s own overlay copy button. +The **Copy button in the action bar** is new — it does not exist in the current `ScriptGeneratorPanel`. It copies `generatedScript` from the store. It is **disabled** when `generatedScript === null` (i.e., before the user has clicked Generate). The draft preview's copy needs are handled by `ScriptPreview`'s existing overlay copy button. No draft-substitution logic needs to be duplicated in `ScriptConfigurePane`. --- @@ -129,7 +129,7 @@ Two sub-states:

Select a template to get started

) : ( -
+
)} @@ -167,7 +167,10 @@ Transitions: 1. `selectTemplate(id)` is called (sets `isLoadingDetail: true` in store) 2. `setPaneMode('configure')` is called immediately — user sees the loading spinner in configure mode -**`selectTemplate` failure case:** If `selectTemplate` throws (network error), the store resets `isLoadingDetail: false` but leaves `selectedTemplate` unchanged. The pane mode remains `'configure'`. If this is the first selection (`selectedTemplate === null`), the configure pane will show neither a spinner nor template content — it will render nothing. `ScriptConfigurePane` must handle this: if `!isLoadingDetail && !selectedTemplate`, render an error state ("Failed to load template. ← Back to library"). +**`selectTemplate` failure case:** If `selectTemplate` throws (network error), the store resets `isLoadingDetail: false` but leaves `selectedTemplate` unchanged. The pane mode remains `'configure'`. + +- **First-selection failure** (`selectedTemplate === null` before the call): `ScriptConfigurePane` must handle `!isLoadingDetail && !selectedTemplate` — render an error state: "Failed to load template." with a "← Back to library" link. +- **Subsequent-selection failure** (`selectedTemplate` is still set from the previous template): the configure pane silently shows the previous template's form with stale data. This is an accepted edge case — network errors mid-session are rare and the user can press Back to recover. No special handling required. **`paramValues` and `formErrors` on Back:** `clearOutput()` does not reset `paramValues` or `formErrors`. This is intentional — if the user returns to browse mode and then clicks "Configure →" on the same template again, `selectTemplate` will repopulate `paramValues` from defaults, discarding any edits. If they configure a different template, `selectTemplate` again repopulates from that template's defaults. There is no scenario where stale param values from a prior template persist into a new template's form. No additional cleanup is needed on Back.