Files
resolutionflow/docs/plans/archive/2026-03-14-parameter-detector-design.md
Michael Chihlas cbb4b25671
All checks were successful
Mirror to GitHub / mirror (push) Successful in 5s
CI / frontend (pull_request) Successful in 6m42s
CI / e2e (pull_request) Successful in 10m11s
CI / backend (pull_request) Successful in 10m43s
fix(ui): drop setState-in-effect in useAuthSessionExpiry
CI surfaced react-hooks/set-state-in-effect on the synchronous
setState(computeState(token)) inside the useEffect body. The earlier
shape mirrored token -> state via an effect, which is exactly the
"you might not need an effect" pattern React 19's eslint rule now
flags.

Switch to derived state: compute during render, use a useReducer
tick to force re-render on the 30s cadence (so relative timestamps
stay current even when token props don't change). Same observable
behavior, no cascading renders.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 20:15:11 -04:00

117 lines
4.1 KiB
Markdown

# 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