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) <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-03-14 18:33:00 -04:00
parent 029502b64a
commit abfa7b4cd3

View File

@@ -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