Design for fixing AI-generated scripts saving to library without parameters, adding parameter detection/review to the save flow, and a "New from Script" paste entry point on the library page. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.0 KiB
Parameterize & Save — Script Library Integration
Date: 2026-03-29 Status: Approved Scope: Fix AI-generated scripts saving to library without parameters; add parameter detection/review to save flow; add "New from Script" paste entry point
Problem
When the AI Script Builder generates a script and the user saves it to the Script Library:
parameters_schemais hardcoded to{"parameters": []}insave_to_library()— no parameter detection runs- The script body uses raw PowerShell
param()syntax, not the{{ key }}template placeholders thatScriptTemplateEngine.render()expects
The result: saved templates have no parameters and can't be rendered with user-provided values. The template engine has nothing to substitute.
The frontend already has working parameter detection (scriptParameterDetector.ts) and a review UI (ParameterDetectorStepper), but they're only wired into ScriptTemplateEditor — not the save-to-library flow.
Solution
A shared ParameterizeAndSavePanel component that:
- Shows the script with live preview of
{{ }}replacements - Auto-runs parameter detection and lets the user review/accept/skip each candidate
- Collects minimal metadata (name, description, category, share toggle)
- Sends the rewritten script body + built parameters schema to the backend
Used in two entry points:
- AI Script Builder — replaces the current
SaveToLibraryDialog - Script Library page — "New from Script" button for pasting raw scripts
Note: Parameter detection currently supports PowerShell only. Bash and Python scripts will show "No parameters detected" and save as-is. Detection for those languages is planned for a future iteration.
Design
ParameterizeAndSavePanel Component
A slide-in panel from the right, ~480px wide, semi-transparent scrim behind it. Close via X button or scrim click.
Layout (top to bottom):
-
Script Preview — read-only code block showing the script body. As parameters are accepted via the stepper, the preview updates live to show
{{ key }}replacements highlighted in amber. -
Parameter Detection Zone — auto-runs
detectParameterCandidates()when the panel opens.- If candidates found: renders the existing
ParameterDetectorStepperinline - If no candidates found: shows "No parameters detected — script will be saved as-is"
- If candidates found: renders the existing
-
Metadata Fields — name (required), description, category dropdown, share-with-team toggle. Same fields as the current
SaveToLibraryDialog. -
Save Button — sends rewritten script body + parameters schema + metadata to the backend.
Two modes controlled by props:
scriptmode (from AI builder): script body + language provided, skips straight to preview + detectionpastemode (from library page): shows a textarea + language picker at the top of the panel, above the preview area. Once pasted and confirmed, textarea collapses into the read-only preview and detection runs.
State: Local React state (not Zustand). Tracks:
workingScript: the in-progress script body, mutated as candidates are acceptedparametersSchema: accumulatedScriptParameter[]arraymetadata: name, description, categoryId, shareWithTeammode: paste vs script (derived from props)
Entry Point 1: AI Script Builder
ScriptBuilderPage currently opens SaveToLibraryDialog. Replace with ParameterizeAndSavePanel in script mode.
Props:
scriptBody:session.latest_scriptlanguage:session.languagedefaultName: suggested filename minus extensiononSave: callsscriptBuilderApi.saveToLibrary()with enriched payloadonClose: closes the panel
Entry Point 2: Script Library Page
Add a "New from Script" button on ScriptLibraryPage (near the "Manage Templates" link). Opens ParameterizeAndSavePanel in paste mode.
Props:
scriptBody:undefined(triggers paste mode)language:undefined(user picks in the panel)onSave: callsscriptsApi.createTemplate()directlyonClose: closes the panel
Backend Changes
SaveToLibraryRequest schema (backend/app/schemas/script_builder.py):
Add two optional fields:
script_body: str | None = None # Rewritten script with {{ }} placeholders
parameters_schema: dict | None = None # Built parameter schema from frontend
save_to_library() service (backend/app/services/script_builder_service.py):
Add script_body: str | None = None and parameters_schema: dict | None = None to the function signature. Use provided values instead of hardcoding:
template = ScriptTemplate(
...
script_body=script_body or session.latest_script,
parameters_schema=parameters_schema or {"parameters": []},
...
)
save_to_library endpoint (backend/app/api/endpoints/script_builder.py):
Pass data.script_body and data.parameters_schema from the request through to the service function.
No new endpoints needed. The library paste flow uses the existing POST /scripts/templates which already accepts script_body + parameters_schema.
Script Rewriting Logic
The ParameterizeAndSavePanel reuses the same approach as ScriptTemplateEditor.handleAcceptCandidate():
When a candidate is accepted:
- Find the matched line in the working script
- Replace the default value portion with
'{{ key }}' - Add the parameter to the accumulated schema
This happens in the panel's local state. The stepper emits accept/skip events; the panel handles the rewriting.
File Changes
New Files
frontend/src/components/scripts/ParameterizeAndSavePanel.tsx— shared panel component
Modified Files
frontend/src/pages/ScriptBuilderPage.tsx— replaceSaveToLibraryDialogwithParameterizeAndSavePanel(script mode)frontend/src/pages/ScriptLibraryPage.tsx— add "New from Script" button, renderParameterizeAndSavePanel(paste mode)backend/app/schemas/script_builder.py— addscript_bodyandparameters_schematoSaveToLibraryRequestbackend/app/services/script_builder_service.py— use provided values insave_to_library()backend/app/api/endpoints/script_builder.py— pass new fields through
Deleted Files
frontend/src/components/script-builder/SaveToLibraryDialog.tsx— replaced entirely
Unchanged (reused as-is)
frontend/src/components/script-editor/ParameterDetectorStepper.tsxfrontend/src/lib/scriptParameterDetector.tsfrontend/src/components/script-editor/ScriptTemplateEditor.tsxPOST /scripts/templatesendpoint
Scope Boundaries
In scope:
ParameterizeAndSavePanelcomponent with script/paste modes- Parameter detection + stepper review in the save flow
- Script body rewriting with
{{ }}placeholders - Backend accepting enriched save payload
- "New from Script" button on library page
- PowerShell parameter detection only
Out of scope:
- Bash/Python parameter detection (future iteration)
- Changes to
ScriptTemplateEditororParameterSchemaBuilder - Changes to
ScriptTemplateEnginerendering logic - New API endpoints