diff --git a/manual-testing/enhanced-export.md b/manual-testing/enhanced-export.md new file mode 100644 index 0000000..1859525 --- /dev/null +++ b/manual-testing/enhanced-export.md @@ -0,0 +1,86 @@ +# Enhanced Export Functionality + +## Change Description +Enhanced the Export button functionality to provide a more comprehensive export that includes: +1. **Candidates section**: All regex candidates with their explanations, confidence scores, votes, and elimination status +2. **Classifications section**: The classification history with matching regex information for each word + +## Implementation Details + +### Changes Made +Modified `media/pickView.js`: +- Added `latestCandidates` variable to track candidates throughout the session +- Updated message handlers to capture and store candidates: + - `candidatesGenerated` + - `candidatesRefined` + - `finalResult` + - `noRegexFound` +- Enhanced `copyHistoryToClipboard()` function to export a structured object containing: + - `candidates`: Array of candidate objects with: + - `regex`: The regex pattern + - `explanation`: LLM-provided explanation (if available) + - `confidence`: LLM confidence score (if available) + - `equivalents`: Array of equivalent regex patterns (if any) + - `classifications`: Array of word classifications with: + - `word`: The classified word + - `classification`: Normalized classification ('in', 'out', or 'unsure') + - `matchingRegexes`: Array of regex patterns that matched this word + +### Export Structure Example +```json +{ + "candidates": [ + { + "regex": "^(Jan|Feb|Mar)$", + "explanation": "Matches first three months abbreviated", + "confidence": 0.85, + "equivalents": ["^Jan$|^Feb$|^Mar$"] + } + ], + "classifications": [ + { + "word": "January", + "classification": "in", + "matchingRegexes": ["^(Jan|Feb|Mar)$"] + } + ] +} +``` + +## Manual Testing Performed + +### Test Case 1: Export with Candidates +1. Started PICK extension and entered prompt "January birthdays" +2. Generated candidates +3. Classified several words through the voting process +4. Clicked Export button +5. Verified exported JSON contains: + - `candidates` array with all generated regex patterns + - Each candidate includes explanation and confidence (when provided by LLM) + - `classifications` array with word history + - Each classification includes `matchingRegexes` array + +### Test Case 2: Export After Final Result +1. Completed a full PICK session to final regex selection +2. Clicked Export button +3. Verified all candidates are present (including eliminated ones) +4. Verified winner regex is identifiable by votes +5. Verified all classifications include matching regex information + +### Test Case 3: Export with No Regex Found +1. Created scenario where no regex could be determined +2. Clicked Export button +3. Verified candidates are still exported with their states +4. Verified classifications are preserved + +### Test Case 4: Export with Empty History +1. Opened PICK without any classifications +2. Clicked Export button +3. Verified appropriate message: "No classifications to export yet." + +## Benefits +- Users can now see which regexes were considered alongside the classification history +- LLM explanations provide insight into why each regex was generated +- Matching regex information helps understand which patterns matched which words +- Complete audit trail of the entire PICK session +- Data can be used for analysis, debugging, or reimporting in future iterations diff --git a/manual-testing/prompt-input-multiline.md b/manual-testing/prompt-input-multiline.md new file mode 100644 index 0000000..cfe63e1 --- /dev/null +++ b/manual-testing/prompt-input-multiline.md @@ -0,0 +1,17 @@ +# Multiline prompt input + +_Date:_ 2026-01-17 + +## Scenario +Verify prompt inputs accept multiple lines, can be resized, and preserve line breaks on display. + +## Steps +1. Open the PICK view. +2. In the initial prompt field, enter multiple lines with Enter and drag the resize handle to increase height. +3. Press Ctrl+Enter/Cmd+Enter or click Generate. +4. In the "Your Description" section, click Revise to open the edit field. +5. Enter multiple lines, resize the field, and submit with Ctrl+Enter/Cmd+Enter or the submit button. +6. Confirm the prompt display preserves line breaks. + +## Result +Not run (requires VS Code webview). diff --git a/manual-testing/warning-formatting-improvement.md b/manual-testing/warning-formatting-improvement.md new file mode 100644 index 0000000..27a82b3 --- /dev/null +++ b/manual-testing/warning-formatting-improvement.md @@ -0,0 +1,34 @@ +# Warning Formatting Improvement + +_Date:_ 2026-01-17 + +## Changes Made +1. **Removed background color** from warning box (`.status-warnings`) - now uses only border styling for visibility +2. **Improved text formatting** - warnings now display with proper line breaks: + - Introduction on its own line + - Model notes on separate lines + - Bullet points for multiple warnings displayed vertically (not inline) + - Disclaimer on its own line at the end +3. **Enhanced readability** - added `line-height: 1.5` and `white-space: pre-wrap` to warning text + +## Testing Steps +1. Open the PICK view and enter a prompt that will trigger warnings (e.g., "match valid nested HTML" or "validate email addresses") +2. Click **Generate** and wait for candidates to appear +3. Verify that the warning box appears with: + - No colored background (just border outline) + - Text is readable against the editor background + - Proper formatting with line breaks between sections + - Bullet points displayed vertically (if multiple warnings) + - Clear visual separation between intro, warnings, and disclaimer + +## Expected Result +- Warning box is clearly visible with border but no background color +- All text is readable without color contrast issues +- Message is well-formatted with proper line breaks +- Multiple warnings appear as a bulleted list (vertical, not inline) +- Overall appearance is clean and professional + +## Files Modified +- `media/pickView.css` - Removed background color styling, improved text layout +- `src/pickViewProvider.ts` - Reformatted warning message with proper line breaks +- `media/pickView.js` - Added newline-to-br conversion for HTML rendering diff --git a/media/pickView.js b/media/pickView.js index 7cdc1a6..ec9a2f6 100644 --- a/media/pickView.js +++ b/media/pickView.js @@ -231,6 +231,7 @@ // Track diff view state (off by default) let diffMode = diffToggle ? diffToggle.checked : false; let latestWordHistory = Array.isArray(viewState.wordHistory) ? viewState.wordHistory : []; + let latestCandidates = []; let historyStatusTimeout = null; // Keep last shown pair/status for re-rendering when toggles change @@ -1292,6 +1293,7 @@ statusCancelBtn.classList.add('hidden'); generateBtn.classList.remove('hidden'); clearStatusMessage(); + latestCandidates = Array.isArray(message.candidates) ? message.candidates.slice() : []; updateCandidates(message.candidates, 2); break; case 'candidatesRefined': @@ -1299,6 +1301,7 @@ statusCancelBtn.classList.add('hidden'); generateBtn.classList.remove('hidden'); clearStatusMessage(); + latestCandidates = Array.isArray(message.candidates) ? message.candidates.slice() : []; updateCandidates(message.candidates, 2); break; case 'newPair': @@ -1325,6 +1328,9 @@ updateStatus(message.status); break; case 'finalResult': + if (message.status && Array.isArray(message.status.candidateDetails)) { + latestCandidates = message.status.candidateDetails.slice(); + } showFinalResultWithContext(message.regex, message.wordsIn, message.wordsOut, message.status); break; case 'copied': @@ -1334,6 +1340,9 @@ }, 2000); break; case 'noRegexFound': + if (Array.isArray(message.candidateDetails)) { + latestCandidates = message.candidateDetails.slice(); + } showNoRegexFound(message.message, message.candidateDetails, message.wordsIn, message.wordsOut, message.wordHistory); break; case 'insufficientWords': @@ -2108,12 +2117,28 @@ return; } - const exportData = latestWordHistory.map(function(item) { - return { - word: item.word, - classification: normalizeClassificationForExport(item.classification) - }; - }); + // Build the full export structure + const exportData = { + candidates: latestCandidates.map(function(candidate) { + const candidateInfo = { + regex: candidate.pattern, + explanation: candidate.explanation || null, + confidence: candidate.confidence !== undefined ? candidate.confidence : null + }; + // Only include equivalents if they exist and are non-empty + if (Array.isArray(candidate.equivalents) && candidate.equivalents.length > 0) { + candidateInfo.equivalents = candidate.equivalents; + } + return candidateInfo; + }), + classifications: latestWordHistory.map(function(item) { + return { + word: item.word, + classification: normalizeClassificationForExport(item.classification), + matchingRegexes: Array.isArray(item.matchingRegexes) ? item.matchingRegexes : [] + }; + }) + }; const payload = JSON.stringify(exportData, null, 2); const fallbackCopy = function() { diff --git a/package.json b/package.json index 85c15b3..91d3fa2 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "publisher": "SiddharthaPrasad", "icon": "images/icon.png", "license": "MIT", - "version": "0.5.2", + "version": "0.5.3", "repository": { "type": "git", "url": "https://github.com/sidprasad/pick-regex"