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:
116
docs/plans/2026-03-14-parameter-detector-design.md
Normal file
116
docs/plans/2026-03-14-parameter-detector-design.md
Normal 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
|
||||
Reference in New Issue
Block a user