Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions manual-testing/enhanced-export.md
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions manual-testing/prompt-input-multiline.md
Original file line number Diff line number Diff line change
@@ -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).
34 changes: 34 additions & 0 deletions manual-testing/warning-formatting-improvement.md
Original file line number Diff line number Diff line change
@@ -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
37 changes: 31 additions & 6 deletions media/pickView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1292,13 +1293,15 @@
statusCancelBtn.classList.add('hidden');
generateBtn.classList.remove('hidden');
clearStatusMessage();
latestCandidates = Array.isArray(message.candidates) ? message.candidates.slice() : [];
updateCandidates(message.candidates, 2);
break;
case 'candidatesRefined':
inlineCancelBtn.classList.add('hidden');
statusCancelBtn.classList.add('hidden');
generateBtn.classList.remove('hidden');
clearStatusMessage();
latestCandidates = Array.isArray(message.candidates) ? message.candidates.slice() : [];
updateCandidates(message.candidates, 2);
break;
case 'newPair':
Expand All @@ -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':
Expand All @@ -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':
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down