# 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
