From abfa7b4cd3a9e490fb1627cf9adfdac203edd6da Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Sat, 14 Mar 2026 18:33:00 -0400 Subject: [PATCH] docs: add parameter detector design doc Client-side PowerShell parameter detection with stepper UI for converting hardcoded values to template parameters. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../2026-03-14-parameter-detector-design.md | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 docs/plans/2026-03-14-parameter-detector-design.md diff --git a/docs/plans/2026-03-14-parameter-detector-design.md b/docs/plans/2026-03-14-parameter-detector-design.md new file mode 100644 index 00000000..9ab65952 --- /dev/null +++ b/docs/plans/2026-03-14-parameter-detector-design.md @@ -0,0 +1,116 @@ +# Parameter Detector — Design Doc + +> **Date:** 2026-03-14 +> **Status:** Approved +> **Scope:** Frontend only (no backend changes) + +## Overview + +A client-side tool in the Script Template Editor that scans a PowerShell script body, detects hardcoded values that should be parameterized, and walks the user through converting them one-by-one via a stepper UI. + +## Detection Engine + +Pure TypeScript utility (`lib/scriptParameterDetector.ts`) that takes a script body string and returns `ParameterCandidate[]`. + +### Detection targets (in order) + +1. **Script-level `param()` blocks** — the `param(...)` block at the top of the script, before any `function` keyword. Extracts name, type annotation, and default value. Skips `param()` blocks inside `function` declarations. +2. **Variable assignments** — `$VarName = 'value'`, `$VarName = "value"`, `$VarName = 123`, `$VarName = $true/$false`. Skips variables already found in the param block and PowerShell internals like `$ErrorActionPreference`. + +### Type inference + +| Detection | Suggested Type | Sensitive | +|-----------|---------------|-----------| +| `[string]` or plain string value | `text` | no | +| `[switch]` or `$true`/`$false` | `boolean` | no | +| `[int]`, `[int32]`, `[int64]` or numeric value | `number` | no | +| `[SecureString]` or name contains password/secret/key/credential | `password` | yes | +| No type info, string value | `text` | no | + +### Candidate shape + +```typescript +interface ParameterCandidate { + variableName: string // "$OUPath" + suggestedKey: string // "ou_path" + suggestedLabel: string // "OU Path" + suggestedType: ScriptParameter['type'] + sensitive: boolean + defaultValue: string | boolean | number | null + source: 'param_block' | 'assignment' + lineNumber: number + matchedLine: string + inferenceReason: string // "Detected [switch] type declaration" +} +``` + +## Stepper UI + +`ParameterDetectorStepper` component renders inline below the ScriptBodyEditor in the Script Body section. + +### Trigger + +- "Detect Parameters" button (secondary style, Wand2/Scan icon) below the script body textarea +- Hidden if script body is empty; disabled while stepper is active +- If no candidates found: brief "No parameter candidates detected" message + +### Stepper layout + +Shows one candidate at a time with: +- Progress indicator ("Candidate 2 of 5" + dots) +- Matched line displayed in monospace +- Editable fields: Key, Label, Type (with info icon showing inferenceReason), Default value +- Checkboxes: Required, Sensitive +- Actions: Skip, Accept & Next (last item: Accept & Finish / Skip & Finish) + +### On accept + +1. Script body: replace the hardcoded value with `{{key}}` +2. Parameters schema: append a new `ScriptParameter` with suggested values + original value as `default` + +### Edge cases + +- Script body edited during detection → stepper dismisses +- Key conflicts with existing parameter → warning + suggested alternative +- Re-running after partial conversion → skips already-converted `{{key}}` placeholders + +## Integration + +### Component tree + +``` +ScriptTemplateEditor +├── Metadata section +├── Script Body section +│ ├── ScriptBodyEditor +│ ├── "Detect Parameters" button ← NEW +│ └── ParameterDetectorStepper ← NEW (conditional) +├── Parameters section +│ └── ParameterSchemaBuilder +└── Fixed Action Bar +``` + +### Data flow + +- Detection runs client-side via `detectParameterCandidates(script_body)` +- Candidates stored in local React state on ScriptTemplateEditor +- Accept updates `form.script_body` and `form.parameters_schema` via existing `updateField()` +- `isDirty` flag set automatically — user can cancel without saving to undo everything +- No new backend endpoints needed + +## File changes + +**New files:** +- `frontend/src/lib/scriptParameterDetector.ts` +- `frontend/src/components/script-editor/ParameterDetectorStepper.tsx` + +**Modified files:** +- `frontend/src/components/script-editor/ScriptTemplateEditor.tsx` +- `frontend/src/types/scripts.ts` + +## Out of scope + +- No backend changes +- No AI-powered detection (future enhancement) +- No auto-detection on paste +- No individual undo for accepted parameters