docs: add comprehensive development workflow documentation

Copilot Integration:
- Streamlined instructions (70% shorter than original)
- Task templates for common operations
- Three-tier usage strategy (free/strategic/manual)
- Optimized for GitHub Copilot Basic tier limits

Development Resources:
- Common task workflows with time estimates
- Feature parity checklist with priorities
- Debugging and troubleshooting guides
- Testing scenarios and checklists
- Code quality standards

Workflow Optimization:
- Efficient Copilot task budgeting
- Real-world implementation examples
- Performance and success metrics
- Project completion roadmap

Reduces repetitive context in prompts.
Maximizes limited Copilot task budget.
This commit is contained in:
Octech2722 2025-10-18 12:21:13 -05:00
parent 57c155ea3f
commit 1f444ebc69
8 changed files with 2609 additions and 0 deletions

View File

@ -0,0 +1,176 @@
# GitHub Copilot Instructions - Trilium Web Clipper MV3
## Project Identity
**Working Directory**: `apps/web-clipper-manifestv3/` (active development)
**Reference Directory**: `apps/web-clipper/` (MV2 legacy - reference only)
**Goal**: Feature-complete MV3 migration with architectural improvements
## Quick Context Links
- Architecture & Systems: See `docs/ARCHITECTURE.md`
- Feature Status: See `docs/FEATURE-PARITY-CHECKLIST.md`
- Development Patterns: See `docs/DEVELOPMENT-GUIDE.md`
- Migration Patterns: See `docs/MIGRATION-PATTERNS.md`
## Critical Rules
### Workspace Boundaries
- ✅ Work ONLY in `apps/web-clipper-manifestv3/`
- ✅ Reference `apps/web-clipper/` for feature understanding
- ❌ DO NOT suggest patterns from other monorepo projects
- ❌ DO NOT copy MV2 code directly
### Code Standards (Non-Negotiable)
1. **No Emojis in Code**: Never use emojis in `.ts`, `.js`, `.json` files, string literals, or code comments
2. **Use Centralized Logging**: `const logger = Logger.create('ComponentName', 'background')`
3. **Use Theme System**: Import `theme.css`, use CSS variables `var(--color-*)`, call `ThemeManager.initialize()`
4. **TypeScript Everything**: Full type safety, no `any` types
5. **Error Handling**: Always wrap async operations in try-catch with proper logging
### Development Mode
- **Current Phase**: Active development (use `npm run dev`)
- **Build**: Watch mode with live reload
- **Focus**: Debugging, rapid iteration, feature implementation
- ⚠️ Only use `npm run build` for final validation
## Essential Patterns
### Message Passing Template
```typescript
// Background service worker
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
(async () => {
try {
const result = await handleMessage(message);
sendResponse({ success: true, data: result });
} catch (error) {
logger.error('Handler error', error);
sendResponse({ success: false, error: error.message });
}
})();
return true; // Required for async
});
```
### Storage Pattern
```typescript
// Use chrome.storage, NEVER localStorage in service workers
await chrome.storage.local.set({ key: value });
const { key } = await chrome.storage.local.get(['key']);
```
### Component Structure
```typescript
import { Logger } from '@/shared/utils';
import { ThemeManager } from '@/shared/theme';
const logger = Logger.create('ComponentName', 'background');
async function initialize() {
await ThemeManager.initialize();
logger.info('Component initialized');
}
```
## When Suggesting Code
### Checklist for Every Response
1. [ ] Verify API usage against `reference/chrome_extension_docs/`
2. [ ] Include proper error handling with centralized logging
3. [ ] Use TypeScript with full type annotations
4. [ ] If UI code: integrate theme system
5. [ ] Reference legacy code for functionality, not implementation
6. [ ] Explain MV2→MV3 changes if applicable
### Response Format
```
**Task**: [What we're implementing]
**Legacy Pattern** (if migrating): [Brief description]
**Modern Approach**: [Show TypeScript implementation]
**Files Modified**: [List affected files]
**Testing**: [How to verify it works]
```
## Common MV3 Patterns
### Service Worker Persistence
```typescript
// State must be stored, not kept in memory
const getState = async () => {
const { state } = await chrome.storage.local.get(['state']);
return state || defaultState;
};
```
### Content Script Communication
```typescript
// Inject scripts programmatically
await chrome.scripting.executeScript({
target: { tabId },
files: ['content.js']
});
```
### Manifest V3 APIs
- `chrome.action` (not browserAction)
- `chrome.storage` (not localStorage)
- `chrome.alarms` (not setTimeout in service worker)
- `declarativeNetRequest` (not webRequest blocking)
## Feature Development Workflow
### Before Starting Work
1. Check `docs/FEATURE-PARITY-CHECKLIST.md` for feature status
2. Review legacy implementation in `apps/web-clipper/`
3. Check if feature needs manifest permissions
4. Plan which files will be modified
### During Development
1. Use centralized logging liberally for debugging
2. Test frequently with `npm run dev` + Chrome reload
3. Check console in both popup and service worker contexts
4. Update feature checklist when complete
### Before Committing
1. Run `npm run type-check`
2. Test all related functionality
3. Verify no console errors
4. Update `FEATURE-PARITY-CHECKLIST.md`
## Current Development Focus
**Phase**: Screenshot Features (see FEATURE-PARITY-CHECKLIST.md)
**Next Priority**: Screenshot cropping implementation
**Key Files**:
- `src/background/index.ts` (capture handlers)
- `src/content/` (selection UI)
- `src/shared/` (utilities)
## What NOT to Include in Suggestions
❌ Long explanations of basic TypeScript concepts
❌ Generic Chrome extension tutorials
❌ Detailed history of MV2→MV3 migration
❌ Code from other monorepo projects
❌ Placeholder/TODO comments without implementation
❌ Overly defensive coding for edge cases not in legacy version
## What TO Focus On
✅ Concrete, working code that solves the task
✅ Feature parity with legacy extension
✅ Modern TypeScript patterns
✅ Proper error handling and logging
✅ Clear migration explanations when relevant
✅ Specific file paths and line references
✅ Testing instructions
## Documentation References
- **Chrome APIs**: `reference/chrome_extension_docs/`
- **Readability**: `reference/Mozilla_Readability_docs/`
- **DOMPurify**: `reference/cure53_DOMPurify_docs/`
- **Cheerio**: `reference/cheerio_docs/`
---
**Remember**: This is an active development project in an existing codebase. Be specific, be practical, and focus on getting features working efficiently. When in doubt, check the architecture docs first.

View File

@ -0,0 +1,377 @@
# <20> Trilium Web Clipper MV3 - Working Status
**Extension Status:** ✅ CORE FUNCTIONALITY WORKING
**Last Updated:** October 17, 2025
**Build System:** esbuild + IIFE
**Target:** Manifest V3 (Chrome/Edge/Brave)
---
## 🚀 Quick Start
```bash
# Make sure you are in the correct working directory
cd apps/web-clipper-manifestv3
# Build
npm run build
# Load in Chrome
chrome://extensions/ → Load unpacked → Select dist/
```
---
## ✅ Implemented & Working
### Core Functionality
- ✅ **Content script injection** (declarative)
- ✅ **Save Selection** to Trilium
- ✅ **Save Page** to Trilium (with Readability + DOMPurify + Cheerio pipeline)
- ✅ **Save Link** (basic - URL + title only)
- ✅ **Save Screenshot** (full page capture, metadata stored)
- ✅ **Duplicate note detection** with user choice (new/update/cancel)
- ✅ **HTML/Markdown/Both** save formats
- ✅ **Context menus** (Save Selection, Save Page, Save Link, Save Screenshot, Save Image)
- ✅ **Keyboard shortcuts** (Ctrl+Shift+S for save, Ctrl+Shift+A for screenshot)
### UI Components
- ✅ **Popup UI** with theming (light/dark/auto)
- ✅ **Settings page** with Trilium connection config
- ✅ **Logs page** with filtering
- ✅ **Toast notifications** (basic success/error)
- ✅ **Connection status** indicator
- ✅ **System theme detection**
### Build System
- ✅ **esbuild** bundling (IIFE format)
- ✅ **TypeScript** compilation
- ✅ **HTML transformation** (script refs fixed)
- ✅ **Asset copying** (CSS, icons, manifest)
- ✅ **Type checking** (`npm run type-check`)
---
## 🔴 Missing Features (vs MV2)
### High Priority
#### 1. **Screenshot Cropping** 🎯 NEXT UP
- **MV2:** `cropImage()` function crops screenshot to selected area
- **MV3:** Crop rectangle stored in metadata but NOT applied to image
- **Impact:** Users get full-page screenshot instead of selected area
- **Solution:** Use OffscreenCanvas API or content script canvas
- **Files:** `src/background/index.ts:504-560`, need crop implementation
#### 2. **Image Processing (Full Page)**
- **MV2:** Downloads all external images, converts to base64, embeds in note
- **MV3:** Only processes images for **selection saves**, not full page
- **Impact:** External images in full-page clips may break/disappear
- **Solution:** Apply `postProcessImages()` to all capture types
- **Files:** `src/background/index.ts:668-740`
#### 3. **Screenshot Selection UI Verification**
- **MV2:** Overlay with drag-to-select, Escape to cancel, visual feedback
- **MV3:** Likely exists in content script but needs testing against MV2
- **Impact:** Unknown - need to verify feature parity
- **Files:** Check `src/content/` against `apps/web-clipper/content.js:66-193`
### Medium Priority
#### 4. **Save Tabs (Bulk Save)**
- **MV2:** "Save tabs" context menu saves all open tabs as single note with links
- **MV3:** Not implemented
- **Impact:** Users can't bulk-save research sessions
- **Solution:** Add context menu + background handler
- **Files:** Reference `apps/web-clipper/background.js:302-326`
#### 5. **"Already Visited" Popup Detection**
- **MV2:** Popup shows if page already clipped, with link to existing note
- **MV3:** Background has `checkForExistingNote()` but popup doesn't use it
- **Impact:** Users don't know if they've already saved a page
- **Solution:** Call `checkForExistingNote()` on popup open, show banner
- **Files:** `src/popup/`, reference `apps/web-clipper/popup/popup.js`
### Low Priority (Quality of Life)
#### 6. **Link with Custom Note**
- **MV2:** Save link with custom text entry (textarea in popup)
- **MV3:** Only saves URL + page title
- **Impact:** Can't add context/thoughts when saving links
- **Solution:** Add textarea to popup for "Save Link" action
- **Files:** `src/popup/index.ts`, `src/background/index.ts:562-592`
#### 7. **Date Metadata Extraction**
- **MV2:** Extracts `publishedDate`/`modifiedDate` from meta tags
- **MV3:** Not implemented
- **Impact:** Lost temporal metadata for articles
- **Solution:** Add meta tag parsing to content script
- **Files:** Add to content script, reference `apps/web-clipper/content.js:44-65`
#### 8. **Interactive Toast Notifications**
- **MV2:** Toasts have "Open in Trilium" and "Close Tabs" buttons
- **MV3:** Basic toasts with text only
- **Impact:** Extra step to open saved notes
- **Solution:** Add button elements to toast HTML
- **Files:** `src/content/toast.ts`, reference `apps/web-clipper/content.js:253-291`
---
## ⚠️ Partially Implemented
| Feature | Status | Gap |
|---------|--------|-----|
| Screenshot capture | ✅ Working | No cropping applied |
| Image processing | ⚠️ Selection only | Full page clips missing |
| Save link | ✅ Basic | No custom note text |
| Toast notifications | ✅ Basic | No interactive buttons |
| Duplicate detection | ✅ Working | Not shown in popup proactively |
---
## 📋 Feature Comparison Matrix
| Feature | MV2 | MV3 | Priority |
|---------|-----|-----|----------|
| **Content Capture** ||||
| Save Selection | ✅ | ✅ | - |
| Save Full Page | ✅ | ✅ | - |
| Save Link | ✅ | ⚠️ Basic | LOW |
| Save Screenshot | ✅ | ⚠️ No crop | **HIGH** |
| Save Image | ✅ | ✅ | - |
| Save Tabs | ✅ | ❌ | MED |
| **Content Processing** ||||
| Readability extraction | ✅ | ✅ | - |
| DOMPurify sanitization | ✅ | ✅ | - |
| Cheerio cleanup | ✅ | ✅ | - |
| Image downloading | ✅ | ⚠️ Partial | **HIGH** |
| Date metadata | ✅ | ❌ | LOW |
| Screenshot cropping | ✅ | ❌ | **HIGH** |
| **Save Formats** ||||
| HTML | ✅ | ✅ | - |
| Markdown | ✅ | ✅ | - |
| Both (parent/child) | ✅ | ✅ | - |
| **UI Features** ||||
| Popup | ✅ | ✅ | - |
| Settings page | ✅ | ✅ | - |
| Logs page | ✅ | ✅ | - |
| Context menus | ✅ | ✅ | - |
| Keyboard shortcuts | ✅ | ✅ | - |
| Toast notifications | ✅ | ⚠️ Basic | LOW |
| Already visited banner | ✅ | ❌ | MED |
| Screenshot selection UI | ✅ | ❓ Unknown | **HIGH** |
| **Connection** ||||
| HTTP/HTTPS servers | ✅ | ✅ | - |
| Desktop app mode | ✅ | ✅ | - |
| Connection testing | ✅ | ✅ | - |
| Auto-reconnect | ✅ | ✅ | - |
---
## 🎯 Current Development Phase
### Phase 1: Critical Features ✅ COMPLETE
- ✅ Build system working
- ✅ Content script injection
- ✅ Basic save functionality
- ✅ Settings & logs UI
### Phase 2: Screenshot Features 🔄 IN PROGRESS
- ⏳ **Task 2.1:** Verify screenshot selection UI
- ⏳ **Task 2.2:** Implement screenshot cropping
- ⏳ **Task 2.3:** Test crop workflow end-to-end
### Phase 3: Image Processing (Planned)
- ⏸️ Apply image processing to full page captures
- ⏸️ Test with various image formats
- ⏸️ Handle CORS edge cases
### Phase 4: Quality of Life (Planned)
- ⏸️ Save tabs feature
- ⏸️ Already visited detection
- ⏸️ Link with custom note
- ⏸️ Date metadata extraction
- ⏸️ Interactive toasts
---
## 🛠️ Build System
**Source:** `src/` (TypeScript)
**Output:** `dist/` (IIFE JavaScript)
**Config:** `build.mjs`
### Key Transformations
- `.ts``.js` (IIFE bundled)
- HTML script refs fixed (`.ts``.js`)
- Paths rewritten for flat structure
- CSS + icons copied
- manifest.json validated
### Common Commands
```bash
# Build for production
npm run build
# Type checking
npm run type-check
# Clean build
npm run clean && npm run build
```
---
## 📂 File Structure
```
dist/
├── background.js # Service worker (IIFE)
├── content.js # Content script (IIFE)
├── popup.js # Popup UI logic (IIFE)
├── options.js # Settings page (IIFE)
├── logs.js # Logs page (IIFE)
├── *.html # HTML files (script refs fixed)
├── *.css # Styles (includes theme.css)
├── icons/ # Extension icons
├── shared/ # Shared assets (theme.css)
└── manifest.json # Chrome extension manifest
```
---
## 🧪 Testing Checklist
### Before Each Build
- [ ] `npm run type-check` passes
- [ ] `npm run build` completes without errors
- [ ] No console errors in background service worker
- [ ] No console errors in content script
### Core Functionality
- [ ] Popup displays correctly
- [ ] Settings page accessible
- [ ] Logs page accessible
- [ ] Connection status shows correctly
- [ ] Theme switching works (light/dark/auto)
### Save Operations
- [ ] Save Selection works
- [ ] Save Page works
- [ ] Save Link works
- [ ] Save Screenshot works (full page)
- [ ] Save Image works
- [ ] Context menu items appear
- [ ] Keyboard shortcuts work
### Error Handling
- [ ] Invalid Trilium URL shows error
- [ ] Network errors handled gracefully
- [ ] Restricted URLs (chrome://) blocked properly
- [ ] Duplicate note dialog works
---
## 🎯 Next Steps
### Immediate (This Session)
1. **Verify screenshot selection UI** exists and works
2. **Implement screenshot cropping** using OffscreenCanvas
3. **Test end-to-end** screenshot workflow
### Short Term (Next Session)
4. Fix image processing for full page captures
5. Add "already visited" detection to popup
6. Implement "save tabs" feature
### Long Term
7. Add custom note text for links
8. Extract date metadata
9. Add interactive toast buttons
10. Performance optimization
11. Cross-browser testing (Firefox, Edge)
---
## 📚 Documentation
- `BUILD-MIGRATION-SUMMARY.md` - Build system details
- `reference/dev_notes/TOAST-NOTIFICATION-IMPLEMENTATION.md` - Toast system
- `reference/chrome_extension_docs/` - Chrome API docs
- `reference/Mozilla_Readability_docs/` - Readability docs
- `reference/cure53_DOMPurify_docs/` - DOMPurify docs
- `reference/cheerio_docs/` - Cheerio docs
---
## 🐛 Known Issues
1. **Screenshot cropping not applied** - Crop rect stored but image not cropped
2. **Images not embedded in full page** - Only works for selections
3. **No "already visited" indicator** - Backend exists, UI doesn't use it
4. **Screenshot selection UI untested** - Need to verify against MV2
---
## 💡 Support
**Issue:** Extension not loading?
**Fix:** Check `chrome://extensions/` errors, rebuild with `npm run build`
**Issue:** Buttons not working?
**Fix:** Open DevTools, check console for errors, verify script paths in HTML
**Issue:** Missing styles?
**Fix:** Check `dist/shared/theme.css` exists after build
**Issue:** Content script not injecting?
**Fix:** Check URL isn't restricted (chrome://, about:, file://)
**Issue:** Can't connect to Trilium?
**Fix:** Verify URL in settings, check CORS headers, test with curl
---
## 🎨 Architecture Notes
### Content Processing Pipeline
```
Raw HTML
Phase 1: Readability (article extraction)
Phase 2: DOMPurify (security sanitization)
Phase 3: Cheerio (final polish)
Clean HTML → Trilium
```
### Save Format Options
- **HTML:** Human-readable, rich formatting (default)
- **Markdown:** AI/LLM-friendly, plain text with structure
- **Both:** HTML parent note + Markdown child note
### Message Flow
```
Content Script → Background → Trilium Server
↑ ↓
Toast Storage/State
```
---
## 🔒 Security
- ✅ DOMPurify sanitization on all HTML
- ✅ CSP compliant (no inline scripts/eval)
- ✅ Restricted URL blocking
- ✅ HTTPS recommended for Trilium connection
- ⚠️ Auth token stored in chrome.storage.local (encrypted by browser)
---
**Status:** 🟢 Ready for Phase 2 Development
**Next Task:** Screenshot Selection UI Verification & Cropping Implementation
Ready to build! 🚀

View File

@ -0,0 +1,264 @@
# Feature Parity Checklist - MV2 to MV3 Migration
**Last Updated**: October 18, 2025
**Current Phase**: Screenshot Features
---
## Status Legend
- ✅ **Complete** - Fully implemented and tested
- 🚧 **In Progress** - Currently being worked on
- ⚠️ **Partial** - Working but missing features
- ❌ **Missing** - Not yet implemented
- ❓ **Unknown** - Needs verification
---
## Core Capture Features
| Feature | Status | Notes | Priority |
|---------|--------|-------|----------|
| Save Selection | ✅ | Working with image processing | - |
| Save Full Page | ✅ | Readability + DOMPurify + Cheerio | - |
| Save Link | ⚠️ | Basic (URL + title only) | LOW |
| Save Screenshot | ⚠️ | No cropping applied | **HIGH** |
| Save Image | ✅ | Downloads and embeds | - |
| Save Tabs (Bulk) | ❌ | Not implemented | MED |
---
## Content Processing
| Feature | Status | Notes | Files |
|---------|--------|-------|-------|
| Readability extraction | ✅ | Working | `background/index.ts:608-630` |
| DOMPurify sanitization | ✅ | Working | `background/index.ts:631-653` |
| Cheerio cleanup | ✅ | Working | `background/index.ts:654-666` |
| Image downloading | ⚠️ | Selection only | `background/index.ts:668-740` |
| Screenshot cropping | ❌ | Rect stored, not applied | `background/index.ts:504-560` |
| Date metadata extraction | ❌ | Not implemented | - |
### Priority Issues:
#### 1. Screenshot Cropping (HIGH)
**Problem**: Full-page screenshot captured, crop rectangle stored in metadata, but crop NOT applied to image.
**MV2 Implementation**: `apps/web-clipper/background.js:393-427` (cropImage function)
**What's Needed**:
- Implement `cropImage()` function in background
- Use OffscreenCanvas API or send to content script
- Apply crop before saving to Trilium
- Test with various screen sizes
**Files to Modify**:
- `src/background/index.ts` (add crop function)
- Possibly `src/content/screenshot.ts` (if canvas needed)
#### 2. Image Processing for Full Page (HIGH)
**Problem**: `postProcessImages()` only runs for selection saves, not full page captures.
**MV2 Implementation**: `apps/web-clipper/background.js:293-301` (downloads all images)
**What's Needed**:
- Call `postProcessImages()` for all capture types
- Handle CORS errors gracefully
- Test with various image formats
- Consider performance for image-heavy pages
**Files to Modify**:
- `src/background/index.ts:608-630` (processContent function)
---
## UI Features
| Feature | Status | Notes | Priority |
|---------|--------|-------|----------|
| Popup interface | ✅ | With theme support | - |
| Settings page | ✅ | Connection config | - |
| Logs viewer | ✅ | Filter/search/export | - |
| Context menus | ✅ | All save types | - |
| Keyboard shortcuts | ✅ | Save (Ctrl+Shift+S), Screenshot (Ctrl+Shift+A) | - |
| Toast notifications | ⚠️ | Basic only | LOW |
| Already visited banner | ❌ | Backend exists, UI doesn't use | MED |
| Screenshot selection UI | ❓ | Needs verification | **HIGH** |
### Priority Issues:
#### 3. Screenshot Selection UI Verification (HIGH)
**Problem**: Unknown if MV3 version has feature parity with MV2 overlay UI.
**MV2 Implementation**: `apps/web-clipper/content.js:66-193`
- Drag-to-select with visual overlay
- Escape key to cancel
- Visual feedback during selection
- Crosshair cursor
**What's Needed**:
- Test MV3 screenshot selection workflow
- Compare UI/UX with MV2 version
- Verify all keyboard shortcuts work
- Check visual styling matches
**Files to Check**:
- `src/content/screenshot.ts`
- `src/content/index.ts`
#### 4. Already Visited Detection (MED)
**Problem**: Popup doesn't show if page was already clipped.
**MV2 Implementation**: `apps/web-clipper/popup/popup.js` (checks on open)
**What's Needed**:
- Call `checkForExistingNote()` when popup opens
- Show banner with link to existing note
- Allow user to still save (update or new note)
**Files to Modify**:
- `src/popup/index.ts`
---
## Save Format Options
| Format | Status | Notes |
|--------|--------|-------|
| HTML | ✅ | Rich formatting preserved |
| Markdown | ✅ | AI/LLM-friendly |
| Both (parent/child) | ✅ | HTML parent + MD child |
---
## Trilium Integration
| Feature | Status | Notes |
|---------|--------|-------|
| HTTP/HTTPS connection | ✅ | Working |
| Desktop app mode | ✅ | Working |
| Connection testing | ✅ | Working |
| Auto-reconnect | ✅ | Working |
| Duplicate detection | ✅ | User choice dialog |
| Parent note selection | ✅ | Working |
| Note attributes | ✅ | Labels and relations |
---
## Quality of Life Features
| Feature | Status | Notes | Priority |
|---------|--------|-------|----------|
| Link with custom note | ❌ | Only URL + title | LOW |
| Date metadata | ❌ | publishedDate, modifiedDate | LOW |
| Interactive toasts | ⚠️ | No "Open in Trilium" button | LOW |
| Save tabs feature | ❌ | Bulk save all tabs | MED |
---
## Current Development Phase
### Phase 1: Core Functionality ✅ COMPLETE
- [x] Build system working
- [x] Content script injection
- [x] Basic save operations
- [x] Settings and logs UI
- [x] Theme system
- [x] Centralized logging
### Phase 2: Screenshot Features 🚧 IN PROGRESS
- [ ] **Task 2.1**: Verify screenshot selection UI against MV2
- [ ] **Task 2.2**: Implement screenshot cropping function
- [ ] **Task 2.3**: Test end-to-end screenshot workflow
- [ ] **Task 2.4**: Handle edge cases (very large/small crops)
**Current Task**: Screenshot selection UI verification
### Phase 3: Image Processing (PLANNED)
- [ ] Apply image processing to full page captures
- [ ] Test with various image formats (PNG, JPG, WebP, SVG)
- [ ] Handle CORS edge cases
- [ ] Performance testing with image-heavy pages
### Phase 4: Quality of Life (PLANNED)
- [ ] Implement "save tabs" feature
- [ ] Add "already visited" detection to popup
- [ ] Add custom note text for links
- [ ] Extract date metadata from pages
- [ ] Add interactive toast buttons
---
## Testing Checklist
### Before Each Session
- [ ] `npm run type-check` passes
- [ ] `npm run dev` running successfully
- [ ] No console errors in service worker
- [ ] No console errors in content script
### Feature Testing
- [ ] Test on regular article pages
- [ ] Test on image-heavy pages
- [ ] Test on dynamic/SPA pages
- [ ] Test on restricted URLs (chrome://)
- [ ] Test with slow network
- [ ] Test with Trilium server down
### Edge Cases
- [ ] Very long pages
- [ ] Pages with many images
- [ ] Pages with embedded media
- [ ] Pages with complex layouts
- [ ] Mobile-responsive pages
---
## Known Issues
### Critical (Blocking)
1. **Screenshot cropping not applied** - Full image saved instead of selection
2. **Images not embedded in full page** - Only works for selection saves
### Important (Should fix)
3. **Screenshot selection UI untested** - Need to verify against MV2
4. **No "already visited" indicator** - Backend function exists but unused
### Nice to Have
5. **No custom note text for links** - Only saves URL and title
6. **No date metadata extraction** - Loses temporal context
7. **Basic toast notifications** - No interactive buttons
---
## Quick Reference: Where Features Live
### Capture Handlers
- **Background**: `src/background/index.ts:390-850`
- **Content Script**: `src/content/index.ts:1-200`
- **Screenshot UI**: `src/content/screenshot.ts`
### UI Components
- **Popup**: `src/popup/`
- **Options**: `src/options/`
- **Logs**: `src/logs/`
### Shared Systems
- **Logging**: `src/shared/utils.ts`
- **Theme**: `src/shared/theme.ts` + `src/shared/theme.css`
- **Types**: `src/shared/types.ts`
---
## Migration Reference
When implementing missing features, compare against MV2:
```
apps/web-clipper/
├── background.js # Service worker logic
├── content.js # Content script logic
└── popup/
└── popup.js # Popup UI logic
```
**Remember**: Reference for functionality, not implementation. Use modern TypeScript patterns.

View File

@ -0,0 +1,548 @@
# MV2 to MV3 Migration Patterns
Quick reference for common migration scenarios when implementing features from the legacy extension.
---
## Pattern 1: Background Page → Service Worker
### MV2 (Don't Use)
```javascript
// Persistent background page with global state
let cachedData = {};
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
cachedData[msg.id] = msg.data;
sendResponse({success: true});
});
```
### MV3 (Use This)
```typescript
// Stateless service worker with chrome.storage
import { Logger } from '@/shared/utils';
const logger = Logger.create('BackgroundHandler', 'background');
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
(async () => {
try {
// Store in chrome.storage, not memory
await chrome.storage.local.set({ [msg.id]: msg.data });
logger.info('Data stored', { id: msg.id });
sendResponse({ success: true });
} catch (error) {
logger.error('Storage failed', error);
sendResponse({ success: false, error: error.message });
}
})();
return true; // Required for async sendResponse
});
```
**Key Changes:**
- No global state (service worker can terminate)
- Use `chrome.storage` for persistence
- Always return `true` for async handlers
- Centralized logging for debugging
---
## Pattern 2: Content Script DOM Manipulation
### MV2 Pattern
```javascript
// Simple DOM access
const content = document.body.innerHTML;
```
### MV3 Pattern (Same, but with error handling)
```typescript
import { Logger } from '@/shared/utils';
const logger = Logger.create('ContentExtractor', 'content');
function extractContent(): string {
try {
if (!document.body) {
logger.warn('Document body not available');
return '';
}
const content = document.body.innerHTML;
logger.debug('Content extracted', { length: content.length });
return content;
} catch (error) {
logger.error('Content extraction failed', error);
return '';
}
}
```
**Key Changes:**
- Add null checks for DOM elements
- Use centralized logging
- Handle errors gracefully
---
## Pattern 3: Screenshot Capture
### MV2 Pattern
```javascript
chrome.tabs.captureVisibleTab(null, {format: 'png'}, (dataUrl) => {
// Crop using canvas
const canvas = document.createElement('canvas');
// ... cropping logic
});
```
### MV3 Pattern
```typescript
import { Logger } from '@/shared/utils';
const logger = Logger.create('ScreenshotCapture', 'background');
async function captureAndCrop(
tabId: number,
cropRect: { x: number; y: number; width: number; height: number }
): Promise<string> {
try {
// Step 1: Capture full tab
const dataUrl = await chrome.tabs.captureVisibleTab(null, {
format: 'png'
});
logger.info('Screenshot captured', { tabId });
// Step 2: Crop using OffscreenCanvas (MV3 service worker compatible)
const response = await fetch(dataUrl);
const blob = await response.blob();
const bitmap = await createImageBitmap(blob);
const offscreen = new OffscreenCanvas(cropRect.width, cropRect.height);
const ctx = offscreen.getContext('2d');
if (!ctx) {
throw new Error('Could not get canvas context');
}
ctx.drawImage(
bitmap,
cropRect.x, cropRect.y, cropRect.width, cropRect.height,
0, 0, cropRect.width, cropRect.height
);
const croppedBlob = await offscreen.convertToBlob({ type: 'image/png' });
const reader = new FileReader();
return new Promise((resolve, reject) => {
reader.onloadend = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(croppedBlob);
});
} catch (error) {
logger.error('Screenshot crop failed', error);
throw error;
}
}
```
**Key Changes:**
- Use `OffscreenCanvas` (available in service workers)
- No DOM canvas manipulation in background
- Full async/await pattern
- Comprehensive error handling
---
## Pattern 4: Image Processing
### MV2 Pattern
```javascript
// Download image and convert to base64
function processImage(imgSrc) {
return new Promise((resolve) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', imgSrc);
xhr.responseType = 'blob';
xhr.onload = () => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(xhr.response);
};
xhr.send();
});
}
```
### MV3 Pattern
```typescript
import { Logger } from '@/shared/utils';
const logger = Logger.create('ImageProcessor', 'background');
async function downloadAndEncodeImage(
imgSrc: string,
baseUrl: string
): Promise<string> {
try {
// Resolve relative URLs
const absoluteUrl = new URL(imgSrc, baseUrl).href;
logger.debug('Downloading image', { url: absoluteUrl });
// Use fetch API (modern, async)
const response = await fetch(absoluteUrl);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const blob = await response.blob();
// Convert to base64
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result as string);
reader.onerror = () => reject(new Error('FileReader failed'));
reader.readAsDataURL(blob);
});
} catch (error) {
logger.warn('Image download failed', { url: imgSrc, error });
// Return original URL as fallback
return imgSrc;
}
}
```
**Key Changes:**
- Use `fetch()` instead of `XMLHttpRequest`
- Handle CORS errors gracefully
- Return original URL on failure (don't break the note)
- Resolve relative URLs properly
---
## Pattern 5: Context Menu Creation
### MV2 Pattern
```javascript
chrome.contextMenus.create({
id: "save-selection",
title: "Save to Trilium",
contexts: ["selection"]
});
```
### MV3 Pattern (Same API, better structure)
```typescript
import { Logger } from '@/shared/utils';
const logger = Logger.create('ContextMenu', 'background');
interface MenuConfig {
id: string;
title: string;
contexts: chrome.contextMenus.ContextType[];
}
const MENU_ITEMS: MenuConfig[] = [
{ id: 'save-selection', title: 'Save Selection to Trilium', contexts: ['selection'] },
{ id: 'save-page', title: 'Save Page to Trilium', contexts: ['page'] },
{ id: 'save-link', title: 'Save Link to Trilium', contexts: ['link'] },
{ id: 'save-image', title: 'Save Image to Trilium', contexts: ['image'] },
{ id: 'save-screenshot', title: 'Save Screenshot to Trilium', contexts: ['page'] }
];
async function setupContextMenus(): Promise<void> {
try {
// Remove existing menus
await chrome.contextMenus.removeAll();
// Create all menu items
for (const item of MENU_ITEMS) {
await chrome.contextMenus.create(item);
logger.debug('Context menu created', { id: item.id });
}
logger.info('Context menus initialized', { count: MENU_ITEMS.length });
} catch (error) {
logger.error('Context menu setup failed', error);
}
}
// Call during service worker initialization
chrome.runtime.onInstalled.addListener(() => {
setupContextMenus();
});
```
**Key Changes:**
- Centralized menu configuration
- Clear typing with interfaces
- Proper error handling
- Logging for debugging
---
## Pattern 6: Sending Messages from Content to Background
### MV2 Pattern
```javascript
chrome.runtime.sendMessage({type: 'SAVE', data: content}, (response) => {
console.log('Saved:', response);
});
```
### MV3 Pattern
```typescript
import { Logger } from '@/shared/utils';
const logger = Logger.create('ContentScript', 'content');
interface SaveMessage {
type: 'SAVE_SELECTION' | 'SAVE_PAGE' | 'SAVE_LINK';
data: {
content: string;
metadata: {
title: string;
url: string;
};
};
}
interface SaveResponse {
success: boolean;
noteId?: string;
error?: string;
}
async function sendToBackground(message: SaveMessage): Promise<SaveResponse> {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage(message, (response: SaveResponse) => {
if (chrome.runtime.lastError) {
logger.error('Message send failed', chrome.runtime.lastError);
reject(new Error(chrome.runtime.lastError.message));
return;
}
if (!response.success) {
logger.warn('Background operation failed', { error: response.error });
reject(new Error(response.error));
return;
}
logger.info('Message handled successfully', { noteId: response.noteId });
resolve(response);
});
});
}
// Usage
try {
const result = await sendToBackground({
type: 'SAVE_SELECTION',
data: {
content: selectedHtml,
metadata: {
title: document.title,
url: window.location.href
}
}
});
showToast(`Saved to Trilium: ${result.noteId}`);
} catch (error) {
logger.error('Save failed', error);
showToast('Failed to save to Trilium', 'error');
}
```
**Key Changes:**
- Strong typing for messages and responses
- Promise wrapper for callback API
- Always check `chrome.runtime.lastError`
- Handle errors at both send and response levels
---
## Pattern 7: Storage Operations
### MV2 Pattern
```javascript
// Mix of localStorage and chrome.storage
localStorage.setItem('setting', value);
chrome.storage.local.get(['data'], (result) => {
console.log(result.data);
});
```
### MV3 Pattern
```typescript
import { Logger } from '@/shared/utils';
const logger = Logger.create('StorageManager', 'background');
// NEVER use localStorage in service workers - it doesn't exist
interface StorageData {
settings: {
triliumUrl: string;
authToken: string;
saveFormat: 'html' | 'markdown' | 'both';
};
cache: {
lastSync: number;
noteIds: string[];
};
}
async function loadSettings(): Promise<StorageData['settings']> {
try {
const { settings } = await chrome.storage.local.get(['settings']);
logger.debug('Settings loaded', { hasToken: !!settings?.authToken });
return settings || getDefaultSettings();
} catch (error) {
logger.error('Settings load failed', error);
return getDefaultSettings();
}
}
async function saveSettings(settings: Partial<StorageData['settings']>): Promise<void> {
try {
const current = await loadSettings();
const updated = { ...current, ...settings };
await chrome.storage.local.set({ settings: updated });
logger.info('Settings saved', { keys: Object.keys(settings) });
} catch (error) {
logger.error('Settings save failed', error);
throw error;
}
}
function getDefaultSettings(): StorageData['settings'] {
return {
triliumUrl: '',
authToken: '',
saveFormat: 'html'
};
}
```
**Key Changes:**
- NEVER use `localStorage` (not available in service workers)
- Use `chrome.storage.local` for all data
- Use `chrome.storage.sync` for user preferences (sync across devices)
- Full TypeScript typing for stored data
- Default values for missing data
---
## Pattern 8: Trilium API Communication
### MV2 Pattern
```javascript
function saveToTrilium(content, metadata) {
const xhr = new XMLHttpRequest();
xhr.open('POST', triliumUrl + '/api/notes');
xhr.setRequestHeader('Authorization', token);
xhr.send(JSON.stringify({content, metadata}));
}
```
### MV3 Pattern
```typescript
import { Logger } from '@/shared/utils';
const logger = Logger.create('TriliumAPI', 'background');
interface TriliumNote {
title: string;
content: string;
type: 'text';
mime: 'text/html' | 'text/markdown';
parentNoteId?: string;
}
interface TriliumResponse {
note: {
noteId: string;
title: string;
};
}
async function createNote(
note: TriliumNote,
triliumUrl: string,
authToken: string
): Promise<string> {
try {
const url = `${triliumUrl}/api/create-note`;
logger.debug('Creating note in Trilium', {
title: note.title,
contentLength: note.content.length
});
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': authToken,
'Content-Type': 'application/json'
},
body: JSON.stringify(note)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`HTTP ${response.status}: ${errorText}`);
}
const data: TriliumResponse = await response.json();
logger.info('Note created successfully', { noteId: data.note.noteId });
return data.note.noteId;
} catch (error) {
logger.error('Note creation failed', error);
throw error;
}
}
```
**Key Changes:**
- Use `fetch()` API (modern, promise-based)
- Full TypeScript typing for requests/responses
- Comprehensive error handling
- Detailed logging for debugging
---
## Quick Reference: When to Use Each Pattern
| Task | Pattern | Files Typically Modified |
|------|---------|-------------------------|
| Add capture feature | Pattern 1, 6, 8 | `background/index.ts`, `content/index.ts` |
| Process images | Pattern 4 | `background/index.ts` |
| Add context menu | Pattern 5 | `background/index.ts` |
| Screenshot with crop | Pattern 3 | `background/index.ts`, possibly `content/screenshot.ts` |
| Settings management | Pattern 7 | `options/index.ts`, `background/index.ts` |
| Trilium communication | Pattern 8 | `background/index.ts` |
---
## Common Gotchas
1. **Service Worker Termination**
- Don't store state in global variables
- Use `chrome.storage` or `chrome.alarms`
2. **Async Message Handlers**
- Always return `true` in listener
- Always check `chrome.runtime.lastError`
3. **Canvas in Service Workers**
- Use `OffscreenCanvas`, not regular `<canvas>`
- No DOM access in background scripts
4. **CORS Issues**
- Handle fetch failures gracefully
- Provide fallbacks for external resources
5. **Type Safety**
- Define interfaces for all messages
- Type all chrome.storage data structures
---
**Usage**: When implementing a feature, find the relevant pattern above and adapt it. Don't copy MV2 code directly—use these proven MV3 patterns instead.

View File

@ -0,0 +1,24 @@
## For Feature Implementation:
Implement [FEATURE_NAME] from FEATURE-PARITY-CHECKLIST.md.
Legacy reference: apps/web-clipper/[FILE]:[LINES]
Target files: src/[FILES]
Use centralized logging and theme system. Update checklist when done.
## For Bug Fixes:
Fix [ISSUE] in src/[FILE].
Expected behavior: [DESCRIBE]
Current behavior: [DESCRIBE]
Error logs: [IF ANY]
## For Code Understanding:
Explain the [FEATURE] implementation in apps/web-clipper/[FILE].
I need to replicate this in MV3. What's the core logic and data flow?
## For Architecture Questions:
[QUESTION ABOUT SYSTEM DESIGN]
See docs/ARCHITECTURE.md for context on logging/theme systems.

View File

@ -0,0 +1,438 @@
# Copilot Task Templates
Quick copy-paste templates for common Copilot tasks. Fill in the blanks and paste into Copilot Agent mode.
---
## Template 1: Implement Feature from Checklist
```
Implement [FEATURE_NAME] from docs/FEATURE-PARITY-CHECKLIST.md.
**Legacy Reference**: apps/web-clipper/[FILE]:[LINE_RANGE]
**Target Files**:
- src/[FILE_1]
- src/[FILE_2]
**Requirements**:
- Use centralized logging (Logger.create)
- Use theme system if UI component
- Follow patterns from docs/MIGRATION-PATTERNS.md
- Handle all errors gracefully
**Testing**:
- Test on [SCENARIO_1]
- Test on [SCENARIO_2]
- Verify no console errors
**Update**:
- Mark feature complete in docs/FEATURE-PARITY-CHECKLIST.md
```
**Example**:
```
Implement screenshot cropping from docs/FEATURE-PARITY-CHECKLIST.md.
**Legacy Reference**: apps/web-clipper/background.js:393-427
**Target Files**:
- src/background/index.ts (add cropImage function)
- src/background/index.ts (update captureScreenshot handler)
**Requirements**:
- Use OffscreenCanvas API (Pattern 3 from docs/MIGRATION-PATTERNS.md)
- Use centralized logging (Logger.create)
- Handle edge cases (crop outside bounds, zero-size crop)
- Handle all errors gracefully
**Testing**:
- Test small crop (100x100)
- Test large crop (full page)
- Test edge crops (near borders)
- Verify cropped dimensions correct
**Update**:
- Mark screenshot cropping complete in docs/FEATURE-PARITY-CHECKLIST.md
```
---
## Template 2: Fix Bug
```
Fix [BUG_DESCRIPTION] in src/[FILE].
**Problem**: [WHAT'S BROKEN]
**Expected Behavior**: [WHAT SHOULD HAPPEN]
**Current Behavior**: [WHAT ACTUALLY HAPPENS]
**Error Logs** (if any):
```
[PASTE ERROR FROM LOGS]
```
**Root Cause** (if known): [HYPOTHESIS]
**Solution Approach**: [HOW TO FIX]
**Testing**:
- Reproduce bug before fix
- Verify fix resolves issue
- Test edge cases
- Check for regressions
```
**Example**:
```
Fix image processing not running on full page captures in src/background/index.ts.
**Problem**: Images not being downloaded and embedded for full-page saves
**Expected Behavior**: All images should be converted to base64 and embedded in the note
**Current Behavior**: Only works for selection saves, full page keeps external URLs
**Root Cause**: postProcessImages() only called in saveSelection handler, not in savePage handler
**Solution Approach**:
1. Call postProcessImages() in processContent function (line ~608)
2. Ensure it runs for all capture types
3. Handle CORS errors gracefully
**Testing**:
- Save full page with multiple images
- Save page with CORS-restricted images
- Verify embedded images display in Trilium
- Check external images still work as fallback
```
---
## Template 3: Add UI Component
```
Add [COMPONENT_NAME] to [PAGE].
**Purpose**: [WHAT IT DOES]
**Visual Design**:
- [DESCRIBE LAYOUT]
- [LIST UI ELEMENTS]
**Data Source**: [WHERE DATA COMES FROM]
**Interactions**:
- [USER ACTION 1] → [RESULT]
- [USER ACTION 2] → [RESULT]
**Files to Modify**:
- src/[PAGE]/[PAGE].html (markup)
- src/[PAGE]/[PAGE].css (styles with theme variables)
- src/[PAGE]/index.ts (logic with logging)
**Requirements**:
- Import and use theme.css
- Initialize ThemeManager
- Use centralized logging
- Handle empty/error states
**Testing**:
- Test in light mode
- Test in dark mode
- Test with no data
- Test with error condition
```
**Example**:
```
Add "Recent Notes" section to popup.
**Purpose**: Show last 5 saved notes with links to open in Trilium
**Visual Design**:
- Card/panel below main action buttons
- Heading "Recently Saved"
- List of note titles (clickable links)
- If empty, show "No recent notes"
**Data Source**:
- chrome.storage.local.recentNotes array
- Populated by background when saving notes
**Interactions**:
- Click note title → Opens note in Trilium (new tab)
**Files to Modify**:
- src/popup/popup.html (add <div> for recent notes)
- src/popup/popup.css (styles with theme variables)
- src/popup/index.ts (load and display recent notes)
- src/background/index.ts (store recent notes on save)
**Requirements**:
- Import and use theme.css with CSS variables
- Initialize ThemeManager
- Use centralized logging
- Handle empty state (no recent notes)
- Escape HTML in note titles
**Testing**:
- Test in light mode
- Test in dark mode
- Test with no recent notes
- Test with 1 note, 5 notes, 10+ notes
- Test note title with special characters
```
---
## Template 4: Refactor Code
```
Refactor [FUNCTION/MODULE] in src/[FILE].
**Current Issues**:
- [PROBLEM 1]
- [PROBLEM 2]
**Goals**:
- [IMPROVEMENT 1]
- [IMPROVEMENT 2]
**Approach**:
- [STEP 1]
- [STEP 2]
**Requirements**:
- Maintain existing functionality (no behavior changes)
- Improve type safety
- Add/improve logging
- Add error handling if missing
**Testing**:
- Verify all existing functionality still works
- Check no regressions
```
---
## Template 5: Investigate Issue
```
Investigate [ISSUE_DESCRIPTION].
**Symptoms**:
- [WHAT USER SEES]
**Context**:
- Happens when [SCENARIO]
- Doesn't happen when [SCENARIO]
**What to Check**:
1. Review relevant code in [FILE]
2. Check logs for errors
3. Check storage state
4. Compare with MV2 implementation (apps/web-clipper/[FILE])
**Expected Output**:
- Root cause analysis
- Proposed solution
- Code changes needed (if applicable)
```
---
## Template 6: Optimize Performance
```
Optimize performance of [FEATURE] in src/[FILE].
**Current Performance**: [METRICS]
**Target Performance**: [GOAL]
**Bottlenecks** (if known):
- [ISSUE 1]
- [ISSUE 2]
**Approach**:
- [OPTIMIZATION 1]
- [OPTIMIZATION 2]
**Requirements**:
- Measure before/after with performance.now()
- Log performance metrics
- Don't break existing functionality
**Testing**:
- Test with small dataset
- Test with large dataset
- Verify functionality unchanged
```
---
## Template 7: Update Documentation
```
Update [DOCUMENTATION_FILE].
**Changes Needed**:
- [CHANGE 1]
- [CHANGE 2]
**Reason**: [WHY UPDATING]
**Files**:
- docs/[FILE]
```
---
## Quick Copilot Commands
### For Understanding Legacy Code
```
Explain the [FEATURE] implementation in apps/web-clipper/[FILE]:[LINES].
Focus on:
- Core logic and data flow
- Key functions and their purpose
- Data structures used
- Edge cases handled
I need to replicate this in MV3 with modern patterns.
```
### For Code Review
```
Review the implementation in src/[FILE].
Check for:
- Proper error handling
- Centralized logging usage
- Theme system integration (if UI)
- Type safety (no 'any' types)
- Edge cases handled
- Performance concerns
Suggest improvements if any.
```
### For Pattern Guidance
```
What's the best MV3 pattern for [TASK]?
Constraints:
- Must work in service worker (no DOM)
- Need to handle [EDGE_CASE]
- Should follow docs/MIGRATION-PATTERNS.md
Show example implementation.
```
---
## Copilot Chat Shortcuts
### Quick Questions (Use Chat Pane - Free)
```
# Understand code
What does this function do?
# Check compatibility
Is this MV3 compatible?
# Get suggestions
How can I improve this?
# Find examples
Show example of [PATTERN]
# Explain error
Why is TypeScript showing this error?
```
### Inline Fixes (Use Ctrl+I - Free)
```
# Fix error
Fix this TypeScript error
# Add types
Add proper TypeScript types
# Improve logging
Add centralized logging
# Format code
Format this properly
# Add comments
Add explanatory comment
```
---
## Usage Tips
### When to Use Templates
1. **Use Template** when:
- Implementing planned feature
- Bug has clear reproduction steps
- Adding designed UI component
- Following established pattern
2. **Ask for Guidance First** when:
- Unclear how to approach problem
- Need to understand legacy code
- Choosing between approaches
- Architectural decision needed
3. **Use Inline Chat** when:
- Fixing TypeScript errors
- Adding missing imports
- Formatting code
- Quick refactoring
### Maximizing Copilot Efficiency
**Before Using Agent Mode (Task)**:
1. Understand the problem clearly
2. Review legacy code if migrating
3. Check docs/MIGRATION-PATTERNS.md for relevant pattern
4. Plan which files need changes
5. Fill out template completely
**During Agent Mode**:
1. Let it work uninterrupted
2. Review generated code carefully
3. Test immediately
4. Use inline chat for small fixes
**After Task**:
1. Update feature checklist
2. Commit with good message
3. Document any decisions
---
## Context File Quick Reference
Point Copilot to these when needed:
```
See docs/ARCHITECTURE.md for system overview
See docs/MIGRATION-PATTERNS.md for coding patterns
See docs/DEVELOPMENT-GUIDE.md for workflow guidance
See docs/FEATURE-PARITY-CHECKLIST.md for current status
See apps/web-clipper/[FILE] for MV2 reference
```
---
**Remember**: Well-prepared prompts = better results + fewer task retries = more efficient Copilot usage!

View File

@ -0,0 +1,2 @@
git add .
git commit -m "feat: [FEATURE_NAME] - [BRIEF_DESCRIPTION]"

View File

@ -0,0 +1,780 @@
# Optimized Copilot Workflow Guide
Complete guide for efficient development with GitHub Copilot Basic tier.
---
## File Structure Overview
```
apps/web-clipper-manifestv3/
├── .github/
│ └── copilot-instructions.md # Auto-loaded by Copilot (streamlined)
├── .vscode/
│ └── settings.json # VS Code + Copilot config
├── docs/
│ ├── ARCHITECTURE.md # One-time reference (systems)
│ ├── FEATURE-PARITY-CHECKLIST.md # Working status + TODO
│ ├── DEVELOPMENT-GUIDE.md # Common tasks + workflows
│ └── MIGRATION-PATTERNS.md # MV2→MV3 code patterns
├── COPILOT-TASK-TEMPLATES.md # Quick copy-paste prompts
├── src/ # Source code
├── reference/ # API documentation
└── dist/ # Build output (gitignored)
```
---
## Step-by-Step Setup
### 1. Reorganize Your Documentation
```bash
cd apps/web-clipper-manifestv3
# Create directory structure
mkdir -p .github docs .vscode
# Move existing file
mv WORKING-STATUS.md docs/FEATURE-PARITY-CHECKLIST.md
# Create new files from artifacts I provided
# (Copy content from the artifacts above)
```
**Files to create**:
1. `.github/copilot-instructions.md` - Streamlined instructions
2. `docs/ARCHITECTURE.md` - System overview
3. `docs/MIGRATION-PATTERNS.md` - Code patterns
4. `docs/DEVELOPMENT-GUIDE.md` - Practical workflows
5. `COPILOT-TASK-TEMPLATES.md` - Quick prompts
6. `.vscode/settings.json` - Editor config
### 2. Update Your Existing Files
**Keep but review**:
- `BUILD-MIGRATION-SUMMARY.md` - Still useful reference
- `reference/` directory - API documentation
**Archive** (move to `docs/archive/` if needed):
- Old verbose documentation
- Duplicate information
- Outdated notes
---
## Three-Tier Copilot Usage Strategy
### Tier 1: Free Operations (Unlimited)
**Use For**: Quick fixes, small changes, understanding code
**Tools**:
- **Inline Chat** (Ctrl+I): Fix errors, add types, format
- **Chat Pane** (Ctrl+Alt+I): Ask questions, get explanations
**Examples**:
```
# Inline Chat (Ctrl+I)
"Fix this TypeScript error"
"Add proper logging"
"Extract this to a function"
# Chat Pane (Ctrl+Alt+I)
"Explain this function"
"What's the MV3 equivalent of chrome.webRequest?"
"How should I structure this component?"
```
**When to Use**:
- Fixing TypeScript errors after implementation
- Understanding unfamiliar code
- Planning before using Agent mode
- Quick refactoring
### Tier 2: Strategic Agent Mode (Limited - Use Wisely)
**Use For**: Multi-file changes, feature implementation, complex logic
**Tool**:
- **Copilot Agent** (from chat pane): Cross-file coordination
**Examples**:
```
# Copy from COPILOT-TASK-TEMPLATES.md, fill in, paste:
Implement screenshot cropping from docs/FEATURE-PARITY-CHECKLIST.md.
Legacy Reference: apps/web-clipper/background.js:393-427
Target Files: src/background/index.ts
Use OffscreenCanvas API (Pattern 3 from docs/MIGRATION-PATTERNS.md).
Use centralized logging.
Update checklist when done.
```
**When to Use**:
- Implementing features from checklist
- Complex multi-file refactoring
- Bug fixes requiring multiple changes
**How to Maximize Value**:
1. **Prepare thoroughly** using Chat Pane first
2. **Use templates** from COPILOT-TASK-TEMPLATES.md
3. **Be specific** about files, patterns, requirements
4. **Let it run** without interruption
5. **Use Inline Chat** for cleanup after
### Tier 3: Manual Development (When Appropriate)
**Use For**: Simple changes, learning opportunities, debugging
**When to Use**:
- Adding a single line of code
- Fixing obvious typos
- Adjusting CSS values
- Learning the codebase
- Quick experiments
---
## Optimal Daily Workflow
### Session Start (5 minutes)
```bash
# 1. Navigate and start build
cd apps/web-clipper-manifestv3
npm run dev
# 2. Open VS Code
code .
# 3. Check current task
# Open: docs/FEATURE-PARITY-CHECKLIST.md
# Find next priority item
```
### Planning Phase (10-15 minutes - Free)
**Use Chat Pane** (Ctrl+Alt+I):
```
1. "Looking at feature [X] in docs/FEATURE-PARITY-CHECKLIST.md,
what's the implementation approach?"
2. "Review the MV2 code in apps/web-clipper/[FILE]:[LINES].
What's the core logic?"
3. "What's the best MV3 pattern for this?
See docs/MIGRATION-PATTERNS.md for our patterns."
4. "What files need to be modified?"
```
**Output**: Clear plan before using Agent mode
### Implementation Phase (Uses 1 Task)
**Use Agent Mode**:
1. Open `COPILOT-TASK-TEMPLATES.md`
2. Copy appropriate template
3. Fill in all blanks
4. Paste into Copilot Agent
5. Let it work
6. Review generated code
**Example Session**:
```
# You paste (from template):
Implement screenshot cropping from docs/FEATURE-PARITY-CHECKLIST.md.
Legacy Reference: apps/web-clipper/background.js:393-427
Target Files:
- src/background/index.ts (add cropImage function)
Requirements:
- Use OffscreenCanvas API (Pattern 3)
- Use centralized logging
- Handle edge cases
Testing:
- Small crops, large crops, edge crops
- Verify dimensions correct
Update: docs/FEATURE-PARITY-CHECKLIST.md
```
### Cleanup Phase (Free)
**Use Inline Chat** (Ctrl+I):
1. Fix any TypeScript errors
2. Add missing imports
3. Improve logging
4. Format code
```
# Select code, press Ctrl+I:
"Fix TypeScript errors"
"Add better error handling"
"Add logging statement"
```
### Testing Phase (Manual)
```bash
# 1. Reload extension in Chrome
chrome://extensions/ → Reload button
# 2. Test functionality
# - Happy path
# - Error cases
# - Edge cases
# 3. Check logs
# - Open extension logs page
# - Filter by component
# - Verify no errors
# 4. Check consoles
# - Service worker console
# - Popup console (if UI)
# - Page console (if content script)
```
### Documentation Phase (Manual)
```bash
# 1. Update checklist
# Edit: docs/FEATURE-PARITY-CHECKLIST.md
# Mark feature as ✅ complete
# 2. Commit changes
git add .
git commit -m "feat: implement screenshot cropping"
# 3. Push (when ready)
git push
```
---
## Task Budgeting Strategy
**With Copilot Basic**: You have limited Agent mode tasks per month.
### Prioritize Tasks For:
**HIGH VALUE (Use Agent Mode)**:
1. ✅ Implementing missing features from checklist
2. ✅ Complex multi-file refactoring
3. ✅ Bug fixes requiring investigation
4. ✅ New component creation with UI
**LOW VALUE (Use Free Tools Instead)**:
1. ❌ Fixing simple TypeScript errors → Use Inline Chat
2. ❌ Understanding code → Use Chat Pane
3. ❌ Small CSS adjustments → Do manually
4. ❌ Adding comments → Use Inline Chat
5. ❌ Renaming variables → Do manually or use VS Code refactor
6. ❌ Formatting code → Use Prettier (Shift+Alt+F)
### Monthly Task Planning
**Estimate your tasks per month**: ~20-30 tasks (varies by plan)
**For this project** (Phase 2 - Screenshot Features):
- Task 1: Screenshot cropping implementation
- Task 2: Image processing for full page
- Task 3: Screenshot selection UI improvements
- **Total**: 3 tasks for Phase 2
**For Phase 3** (Image Processing):
- Task 4: Apply image processing to all capture types
- Task 5: CORS error handling improvements
- **Total**: 2 tasks for Phase 3
**For Phase 4** (Quality of Life):
- Task 6: Save tabs feature
- Task 7: Already visited detection
- Task 8: Custom note text for links
- **Total**: 3 tasks for Phase 4
**Total for project completion**: ~8-10 Agent mode tasks
---
## Real-World Example: Implementing Screenshot Cropping
Let's walk through a complete feature implementation using the optimized workflow.
### Phase 1: Planning (Free - Chat Pane)
**You ask**:
```
I need to implement screenshot cropping for the extension. The current
implementation captures full-page screenshots but doesn't apply the crop
rectangle that's stored in metadata.
MV2 implementation: apps/web-clipper/background.js:393-427
Questions:
1. Can I use regular Canvas in a service worker, or do I need OffscreenCanvas?
2. What's the best way to crop the image?
3. How should I handle errors?
See docs/MIGRATION-PATTERNS.md Pattern 3 for reference.
```
**Copilot responds** (paraphrased):
```
1. Must use OffscreenCanvas - regular Canvas requires DOM
2. Best approach:
- Convert dataURL to Blob
- Create ImageBitmap from Blob
- Draw cropped section to OffscreenCanvas
- Convert back to dataURL
3. Handle errors:
- Invalid crop dimensions (width/height <= 0)
- Crop outside image bounds
- Canvas context creation failure
Here's the basic structure:
[Shows code structure]
```
**Output**: Clear implementation plan, no task used.
### Phase 2: Implementation (Uses 1 Task)
**You prepare the prompt** (from template):
```
Implement screenshot cropping from docs/FEATURE-PARITY-CHECKLIST.md.
**Legacy Reference**: apps/web-clipper/background.js:393-427
**Target Files**:
- src/background/index.ts (add cropImage function around line 500)
- src/background/index.ts (update captureScreenshot handler to call cropImage)
**Requirements**:
- Use OffscreenCanvas API (service worker compatible)
- Follow Pattern 3 from docs/MIGRATION-PATTERNS.md
- Use centralized logging (Logger.create('ScreenshotCrop', 'background'))
- Handle edge cases:
- Crop dimensions <= 0 (return error)
- Crop outside image bounds (clamp to bounds)
- Canvas context creation failure (log and throw)
- Return cropped image as base64 dataURL
**Implementation Details**:
1. Create async function `cropImage(dataUrl: string, cropRect: CropRect): Promise<string>`
2. Convert dataURL to Blob using fetch
3. Create ImageBitmap from Blob
4. Create OffscreenCanvas with crop dimensions
5. Draw cropped section using drawImage with source/dest rects
6. Convert to Blob, then back to dataURL
7. Log success with final dimensions
**Testing**:
- Small crop (100x100px)
- Large crop (full viewport)
- Edge crop (near image borders)
- Invalid crop (negative dimensions) - should error
- Verify cropped image dimensions match crop rect
**Update**:
- Mark "Screenshot cropping" as ✅ in docs/FEATURE-PARITY-CHECKLIST.md
- Add comment about implementation in checklist
```
**Copilot implements**: Multiple files, full feature.
### Phase 3: Cleanup (Free - Inline Chat)
**You notice**: Some TypeScript errors, missing null checks.
**You do** (Ctrl+I on error):
```
"Fix this TypeScript error"
"Add null check for canvas context"
"Improve error message"
```
**Result**: Clean, type-safe code.
### Phase 4: Testing (Manual)
```bash
# Reload extension
chrome://extensions/ → Reload
# Test cases
1. Visit any webpage
2. Press Ctrl+Shift+A (screenshot shortcut)
3. Drag to select small area
4. Save to Trilium
5. Check image in Trilium - should be cropped
# Check logs
- Open extension Logs page
- Search "crop"
- Should see "Screenshot cropped" with dimensions
- Should see "Screenshot captured" with dimensions
- No errors
# Test edge cases
- Try very small crop (10x10)
- Try very large crop (full page)
- Try crop at page edge
```
### Phase 5: Documentation (Manual)
```bash
# Update checklist
# In docs/FEATURE-PARITY-CHECKLIST.md:
## Content Processing
| Screenshot cropping | ✅ | Using OffscreenCanvas | - |
# Commit
git add docs/FEATURE-PARITY-CHECKLIST.md src/background/index.ts
git commit -m "feat: implement screenshot cropping with OffscreenCanvas
- Add cropImage function using OffscreenCanvas API
- Update captureScreenshot handler to apply crop
- Handle edge cases (invalid dimensions, out of bounds)
- Add comprehensive logging and error handling
- Tested with various crop sizes and positions
Closes #XX (if issue exists)"
# Push when ready
git push origin feature/screenshot-cropping
```
**Total Time**:
- Planning: 10 min (free)
- Implementation: 5 min (1 task)
- Cleanup: 5 min (free)
- Testing: 15 min (manual)
- Documentation: 5 min (manual)
- **Total**: ~40 minutes, 1 task used
---
## Troubleshooting Copilot Issues
### Issue: Copilot Not Using copilot-instructions.md
**Check**:
1. File must be at `.github/copilot-instructions.md`
2. VS Code setting must reference it
3. Restart VS Code after creating file
**Fix**:
```json
// In .vscode/settings.json
{
"github.copilot.chat.codeGeneration.instructions": [
{
"file": ".github/copilot-instructions.md"
}
]
}
```
### Issue: Copilot Suggests Wrong Patterns
**Cause**: Instructions too vague or missing context
**Fix**: Be more specific in prompts
```
# ❌ Vague
"Add screenshot feature"
# ✅ Specific
"Implement screenshot cropping using OffscreenCanvas API.
See Pattern 3 in docs/MIGRATION-PATTERNS.md.
Target file: src/background/index.ts around line 500."
```
### Issue: Copilot Runs Out of Context
**Cause**: Trying to process too many files at once
**Fix**: Break into smaller tasks
```
# ❌ Too broad
"Implement all screenshot features"
# ✅ Focused
"Implement screenshot cropping in src/background/index.ts"
[Then in next task]
"Add screenshot selection UI improvements in src/content/screenshot.ts"
```
### Issue: Generated Code Doesn't Follow Project Patterns
**Cause**: Copilot didn't read migration patterns
**Fix**: Reference specific patterns
```
"Implement X using Pattern Y from docs/MIGRATION-PATTERNS.md.
Use centralized logging (Logger.create).
Use theme system for UI."
```
---
## Advanced Tips
### Tip 1: Pre-Load Context in Chat
Before using Agent mode, load context in Chat Pane:
```
# In Chat Pane (free):
"Review docs/MIGRATION-PATTERNS.md Pattern 3"
"Review apps/web-clipper/background.js:393-427"
"Review docs/FEATURE-PARITY-CHECKLIST.md screenshot section"
# Then use Agent mode with:
"Now implement screenshot cropping as discussed"
```
**Benefit**: Copilot has context loaded, better results.
### Tip 2: Use Multi-Turn Conversations
Instead of one complex prompt, break into conversation:
```
# Turn 1 (Chat Pane):
"What's the best way to crop screenshots in MV3 service worker?"
# Turn 2:
"Show me example code using OffscreenCanvas"
# Turn 3:
"Now adapt that for our project structure.
Target: src/background/index.ts, use our Logger"
# Turn 4 (Agent Mode):
"Implement this in the project"
```
**Benefit**: Iterative refinement, only uses 1 task at the end.
### Tip 3: Create Code Snippets for Common Patterns
In VS Code, create snippets (File → Preferences → User Snippets):
```json
{
"Message Handler": {
"prefix": "msg-handler",
"body": [
"chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {",
" (async () => {",
" try {",
" const result = await handle${1:Action}(message);",
" sendResponse({ success: true, data: result });",
" } catch (error) {",
" logger.error('${1:Action} handler error', error);",
" sendResponse({ success: false, error: error.message });",
" }",
" })();",
" return true;",
"});"
]
}
}
```
**Benefit**: Common patterns without using any Copilot resources.
### Tip 4: Batch Similar Tasks
When implementing multiple similar features:
```
# Instead of 3 separate Agent tasks:
Task 1: Add "Save Tabs" context menu
Task 2: Add "Save Tabs" handler
Task 3: Add "Save Tabs" to manifest
# Do in 1 Agent task:
"Implement complete 'Save Tabs' feature:
- Add context menu item
- Add message handler in background
- Update manifest permissions
- Add to docs/FEATURE-PARITY-CHECKLIST.md"
```
**Benefit**: 3x fewer tasks used.
### Tip 5: Use Git Diffs for Review
Before committing, review with Copilot:
```
# In Chat Pane (free):
"Review my changes in src/background/index.ts.
Check for:
- Proper error handling
- Centralized logging
- Type safety
- Edge cases"
```
**Benefit**: Code review without using a task.
---
## Measuring Success
Track these metrics to optimize your workflow:
### Time Metrics
- **Planning time**: How long to prepare a good prompt
- **Implementation time**: How long Copilot takes
- **Cleanup time**: How much fixing needed after
- **Testing time**: How long to verify functionality
**Goal**: Minimize cleanup time through better prompts.
### Quality Metrics
- **First-time success rate**: Does implementation work immediately?
- **Error count**: How many TypeScript/runtime errors?
- **Test pass rate**: Does it work in all test scenarios?
**Goal**: >80% first-time success rate.
### Efficiency Metrics
- **Tasks used per feature**: How many Agent mode tasks?
- **Rework count**: How many times did you need to fix?
- **Documentation accuracy**: Are docs up to date?
**Goal**: <2 tasks per feature on average.
---
## Project Completion Roadmap
Using this workflow, here's your path to completion:
### Phase 2: Screenshot Features (Current)
- [ ] Task 1: Implement screenshot cropping (~40 min, 1 task)
- [ ] Task 2: Verify/improve screenshot selection UI (~30 min, 1 task)
- [ ] Manual: Update documentation and testing (~20 min)
- **Total**: ~90 minutes, 2 tasks
### Phase 3: Image Processing
- [ ] Task 3: Apply image processing to all captures (~45 min, 1 task)
- [ ] Manual: Test with various image types (~30 min)
- [ ] Manual: Update documentation (~15 min)
- **Total**: ~90 minutes, 1 task
### Phase 4: Quality of Life Features
- [ ] Task 4: Implement "Save Tabs" (~40 min, 1 task)
- [ ] Task 5: Add "Already Visited" detection (~35 min, 1 task)
- [ ] Task 6: Add custom note text for links (~30 min, 1 task)
- [ ] Manual: Comprehensive testing (~60 min)
- [ ] Manual: Final documentation (~30 min)
- **Total**: ~3 hours, 3 tasks
### Phase 5: Polish & PR
- [ ] Manual: Full feature testing (~2 hours)
- [ ] Task 7: Final refactoring (if needed) (~30 min, 1 task)
- [ ] Manual: Write PR description (~30 min)
- [ ] Manual: Address review comments (varies)
- **Total**: ~3+ hours, 1 task
**Grand Total**:
- ~7-8 hours of development
- ~8 Agent mode tasks
- Ready for production PR
---
## Quick Reference Card
Print or keep open while developing:
```
╔════════════════════════════════════════════════════╗
║ COPILOT WORKFLOW QUICK REFERENCE ║
╠════════════════════════════════════════════════════╣
║ PLANNING (Free) ║
║ • Ctrl+Alt+I → Ask questions ║
║ • Review legacy code in chat ║
║ • Check docs/MIGRATION-PATTERNS.md ║
║ • Plan which files to modify ║
╠════════════════════════════════════════════════════╣
║ IMPLEMENTING (Uses Task) ║
║ • Copy template from COPILOT-TASK-TEMPLATES.md ║
║ • Fill in all blanks ║
║ • Paste to Agent mode ║
║ • Let it work ║
╠════════════════════════════════════════════════════╣
║ CLEANUP (Free) ║
║ • Ctrl+I → Fix TypeScript errors ║
║ • Ctrl+I → Add logging/types ║
║ • Shift+Alt+F → Format code ║
╠════════════════════════════════════════════════════╣
║ TESTING (Manual) ║
║ • chrome://extensions/ → Reload ║
║ • Test happy path + edge cases ║
║ • Check Logs page ║
║ • Verify consoles (SW, popup, content) ║
╠════════════════════════════════════════════════════╣
║ DOCUMENTING (Manual) ║
║ • Update docs/FEATURE-PARITY-CHECKLIST.md ║
║ • git commit -m "feat: description" ║
╠════════════════════════════════════════════════════╣
║ KEY FILES ║
║ • .github/copilot-instructions.md (auto-loaded) ║
║ • docs/FEATURE-PARITY-CHECKLIST.md (status) ║
║ • docs/MIGRATION-PATTERNS.md (code patterns) ║
║ • COPILOT-TASK-TEMPLATES.md (copy-paste) ║
╠════════════════════════════════════════════════════╣
║ ALWAYS INCLUDE IN PROMPTS ║
║ • Target files with line numbers ║
║ • Reference to relevant pattern/docs ║
║ • "Use centralized logging" ║
║ • "Update FEATURE-PARITY-CHECKLIST.md" ║
╚════════════════════════════════════════════════════╝
```
---
## Next Steps
1. **Right Now**:
- Create the new file structure
- Copy content from artifacts to new files
- Review and understand the workflow
2. **Today**:
- Implement one small feature using the workflow
- Get comfortable with the templates
- Measure your time and task usage
3. **This Week**:
- Complete Phase 2 (Screenshot Features)
- Refine your prompts based on results
- Update templates if needed
4. **This Month**:
- Complete Phases 3-4
- Prepare pull request
- Document any workflow improvements
---
**Remember**: The goal is to work smarter, not harder. Good preparation = better results = fewer tasks used = faster completion!
Ready to implement! 🚀