|
| 1 | +# Staged ShareSurfer TUI Design |
| 2 | + |
| 3 | +## Decision |
| 4 | + |
| 5 | +ShareSurfer will take a staged TUI path: |
| 6 | + |
| 7 | +1. **C now:** build a dependency-free internal console layer and use it to make ownership import feel like a real guided wizard. |
| 8 | +2. **B later:** consider a richer/full-screen TUI or companion only after the stable console layer exists, the collector prompts are consistent, and the team can evaluate the cost of richer terminal behavior with real operator feedback. |
| 9 | + |
| 10 | +This replaces the current prompt-control experience, which technically supports back/skip/help but still feels like a stack of `Read-Host` prompts instead of a guided tool. |
| 11 | + |
| 12 | +## Why Not A Framework TUI First |
| 13 | + |
| 14 | +ShareSurfer's collector runs in Windows PowerShell 5.1, in offline and nonpermissive environments, from an unsigned pre-1.0 ZIP. Operators need transcripts, scrollback, command previews, copy/pasteable rerun scripts, and readable troubleshooting evidence. |
| 15 | + |
| 16 | +A third-party framework or full-screen alternate-buffer TUI would add risk before the workflow is stable: |
| 17 | + |
| 18 | +- extra assemblies or runtime dependencies to explain to security teams; |
| 19 | +- more signing and packaging work before the base experience is proven; |
| 20 | +- possible breakage in older Windows consoles; |
| 21 | +- weaker transcript and scrollback behavior; |
| 22 | +- harder snapshot testing; |
| 23 | +- less predictable accessibility behavior. |
| 24 | + |
| 25 | +The near-term goal is not visual spectacle. It is to make the console feel calm, guided, reversible, and understandable. |
| 26 | + |
| 27 | +## Near-Term Architecture |
| 28 | + |
| 29 | +Add an internal console layer, tentatively `src/ShareSurfer/Private/ShareSurfer.Console.ps1`. |
| 30 | + |
| 31 | +This layer should not export public commands. It should provide internal helpers used by startup, ownership import, CSV picking, OU picking, and future guided flows. |
| 32 | + |
| 33 | +Core helpers: |
| 34 | + |
| 35 | +- `Get-ShareSurferConsoleCapabilities`: detect raw-key support, redirected input/output, width, color support, and `NO_COLOR`. |
| 36 | +- `New-ShareSurferConsoleChoiceState`: deterministic choice state for tests. |
| 37 | +- `Invoke-ShareSurferConsoleChoiceCommand`: apply commands such as up, down, select, skip, back, help, quit, and typed number. |
| 38 | +- `Read-ShareSurferConsoleChoice`: interactive choice reader with raw-key support where available and numbered fallback everywhere else. |
| 39 | +- `Read-ShareSurferConsoleText`: text prompt with default, help, validation, back, quit, and clear error messages. |
| 40 | +- `Read-ShareSurferConsoleBoolean`: yes/no prompt using the same control model. |
| 41 | +- `Read-ShareSurferConsoleMultiSelect`: reusable multi-select engine for CSV and OU pickers. |
| 42 | +- `Write-ShareSurferConsoleLines`: one output sink for rendered screens. |
| 43 | + |
| 44 | +Every visible screen should be generated as `[string[]]` first, then written by the sink. This makes transcript snapshot tests practical and prevents every prompt from inventing its own formatting. |
| 45 | + |
| 46 | +## Ownership Import Wizard First |
| 47 | + |
| 48 | +The first implementation slice should focus on ownership import because that is where the current experience hurt most. |
| 49 | + |
| 50 | +The ownership wizard should show: |
| 51 | + |
| 52 | +- title and source file; |
| 53 | +- step number and total fields; |
| 54 | +- current field name; |
| 55 | +- whether the field is recommended or optional; |
| 56 | +- suggested source header, when one exists; |
| 57 | +- available headers, compactly displayed; |
| 58 | +- short explanation of why the field matters; |
| 59 | +- current controls line; |
| 60 | +- current mapped/skipped state summary. |
| 61 | + |
| 62 | +Example shape: |
| 63 | + |
| 64 | +```text |
| 65 | +ShareSurfer Ownership Import |
| 66 | +Source: hr-export.csv |
| 67 | +Step 3/22 - EmployeeId (recommended) |
| 68 | +
|
| 69 | +Suggested header |
| 70 | +> EmployeeID |
| 71 | +
|
| 72 | +Available headers |
| 73 | +1 EmployeeID 2 Name 3 Mail 4 OBSPath 5 ProjectCode |
| 74 | +
|
| 75 | +Why this matters |
| 76 | +EmployeeId is usually the strongest join key for matching HR data to AD accounts. |
| 77 | +
|
| 78 | +Controls |
| 79 | +Enter=accept | arrows/numbers=choose | S=skip | B=back | ?=help | Q=quit |
| 80 | +``` |
| 81 | + |
| 82 | +For source classification, the same layer should show source type, authority level, and primary anchor choices with short plain-English descriptions. |
| 83 | + |
| 84 | +## Behavior Contract |
| 85 | + |
| 86 | +The console layer should use one controls contract everywhere: |
| 87 | + |
| 88 | +```text |
| 89 | +Enter=accept | arrows/numbers=choose | S=skip | B=back | ?=help | Q=quit |
| 90 | +``` |
| 91 | + |
| 92 | +Behavior rules: |
| 93 | + |
| 94 | +- `Enter` accepts the default or selected item. |
| 95 | +- Arrow keys move selection only when raw-key input is safe. |
| 96 | +- Numbers always work as fallback selection. |
| 97 | +- `S` skips only when the current prompt permits skip. |
| 98 | +- `B` returns to the previous wizard field without losing current state. |
| 99 | +- `?` shows contextual help. |
| 100 | +- `Q` cancels the current guided flow with a clear message. |
| 101 | +- Cancel should not partially overwrite mapping profiles, definition JSON, or rerun scripts. |
| 102 | + |
| 103 | +Where the console cannot safely read raw keys, the same screens should still work with typed numbers and typed commands. |
| 104 | + |
| 105 | +## Reusable Output Contract |
| 106 | + |
| 107 | +The improved TUI must preserve existing durable outputs: |
| 108 | + |
| 109 | +- mapping profile JSON; |
| 110 | +- ownership import definition JSON; |
| 111 | +- ownership enrichment CSV; |
| 112 | +- reusable rerun scripts; |
| 113 | +- startup JSON config; |
| 114 | +- operator assistant plan JSON. |
| 115 | + |
| 116 | +The TUI can improve how choices are made, but non-interactive replay must stay compatible. A saved definition should not require re-answering interactive questions. |
| 117 | + |
| 118 | +## Testing Strategy |
| 119 | + |
| 120 | +Tests should favor deterministic state and render output over trying to automate a real terminal. |
| 121 | + |
| 122 | +Required test lanes: |
| 123 | + |
| 124 | +- choice state machine: up/down/select/number/back/skip/help/quit; |
| 125 | +- key translation: arrow keys, enter, escape, backspace, zero-character modifier keys, and unsupported function keys; |
| 126 | +- render snapshots: ownership field screen, source type screen, authority screen, primary anchor screen, validation error screen; |
| 127 | +- header interview: back edits a prior field, skip stays blank, quit does not write partial output; |
| 128 | +- fallback mode: typed-number selection works when raw keys are unavailable; |
| 129 | +- compatibility: existing `-DefinitionPath`, mapping profile, and rerun tests still pass. |
| 130 | + |
| 131 | +The existing PowerShell suite remains the main local gate: |
| 132 | + |
| 133 | +```powershell |
| 134 | +pwsh -NoLogo -NoProfile -File tests/Invoke-ShareSurferTests.ps1 |
| 135 | +``` |
| 136 | + |
| 137 | +Dashboard tests are not required unless dashboard files change. |
| 138 | + |
| 139 | +## Implementation Sequence |
| 140 | + |
| 141 | +### Slice 1: Console Layer Foundation |
| 142 | + |
| 143 | +- Create `ShareSurfer.Console.ps1`. |
| 144 | +- Move the existing prompt-choice state machine out of `Join-ShareSurferOwnershipSources.ps1`. |
| 145 | +- Add capability detection and render-to-string helpers. |
| 146 | +- Add tests for state, key translation, and plain rendering. |
| 147 | +- Preserve current behavior through compatibility shims. |
| 148 | + |
| 149 | +### Slice 2: Ownership Import Wizard |
| 150 | + |
| 151 | +- Rework `Read-ShareSurferOwnershipHeaderSelections` to render full wizard screens through the console layer. |
| 152 | +- Add field explanations for canonical ownership fields. |
| 153 | +- Preserve mapping profile and definition replay behavior. |
| 154 | +- Add snapshot tests and cancellation tests. |
| 155 | + |
| 156 | +### Slice 3: Source Classification Wizard |
| 157 | + |
| 158 | +- Rework source type, authority level, and primary anchor prompts through the console layer. |
| 159 | +- Improve explanations for `Identity`, `ObsContext`, `ProjectContext`, `PathOwnership`, `GroupContext`, and `Mixed`. |
| 160 | +- Add tests for defaults, alternate selections, back, and quit. |
| 161 | + |
| 162 | +### Slice 4: Broader Prompt Convergence |
| 163 | + |
| 164 | +- Convert startup prompts, operator assistant prompts, CSV picker, and forbidden-OU picker to the same layer. |
| 165 | +- Add breadcrumbs and selection summaries. |
| 166 | +- Add a test that blocks new ad hoc `Read-Host` loops outside approved prompt-layer code. |
| 167 | + |
| 168 | +### Slice 5: Start-ShareSurfer Home Menu |
| 169 | + |
| 170 | +- Add a start menu shell over existing flows. |
| 171 | +- Show readiness states for preflight, ownership inputs, scan, validate, package dashboard, handoff, and support bundle. |
| 172 | +- Every menu action previews the exact command before running. |
| 173 | +- State is saved through existing JSON files. |
| 174 | + |
| 175 | +## Later Rich TUI Direction |
| 176 | + |
| 177 | +After the internal console layer is stable, evaluate a richer TUI as a separate project. |
| 178 | + |
| 179 | +The later richer TUI could include: |
| 180 | + |
| 181 | +- in-place redraw; |
| 182 | +- color accents; |
| 183 | +- searchable pickers; |
| 184 | +- side-by-side panels; |
| 185 | +- a fuller menu shell; |
| 186 | +- possibly a signed companion application or richer dashboard-adjacent experience. |
| 187 | + |
| 188 | +That later work must not become a collector dependency until it clears these gates: |
| 189 | + |
| 190 | +- works on target Windows admin workstations; |
| 191 | +- does not break transcripts or evidence capture; |
| 192 | +- is packageable and eventually signable; |
| 193 | +- has a plain console fallback; |
| 194 | +- does not require internet access at runtime. |
| 195 | + |
| 196 | +## Acceptance Criteria For The First Build |
| 197 | + |
| 198 | +The first build should be considered successful when: |
| 199 | + |
| 200 | +- ownership import feels like a guided wizard rather than repeated raw prompts; |
| 201 | +- back, skip, help, quit, and number fallback behave consistently; |
| 202 | +- raw-key support improves normal consoles without being required; |
| 203 | +- saved JSON and rerun outputs remain compatible; |
| 204 | +- render snapshots prove the visible screens; |
| 205 | +- the full PowerShell suite passes; |
| 206 | +- docs show the new wizard behavior plainly for first-time admins. |
| 207 | + |
| 208 | +## Explicit Non-Goals |
| 209 | + |
| 210 | +- No third-party TUI framework in the near-term collector path. |
| 211 | +- No full-screen alternate-buffer application in the first slice. |
| 212 | +- No dependency on PowerShell 7, npm, internet access, or a GUI. |
| 213 | +- No changes to ownership merge semantics beyond what is needed to preserve prompt choices. |
| 214 | +- No dashboard redesign as part of this TUI slice. |
| 215 | + |
| 216 | +## Open Follow-Up |
| 217 | + |
| 218 | +The later richer TUI should be tracked as a long-term goal after the console layer proves itself in the field. The immediate release path should focus on the internal console layer and ownership import wizard first. |
0 commit comments