history.js
1 import { cli, Strategy } from '@jackwener/opencli/registry'; 2 export const historyCommand = cli({ 3 site: 'chatwise', 4 name: 'history', 5 description: 'List conversation history in ChatWise sidebar', 6 domain: 'localhost', 7 strategy: Strategy.UI, 8 browser: true, 9 args: [], 10 columns: ['Index', 'Title'], 11 func: async (page) => { 12 const items = await page.evaluate(` 13 (function() { 14 const results = []; 15 const selectors = [ 16 '[class*="sidebar"] [class*="item"]', 17 '[class*="conversation-list"] a', 18 '[class*="chat-list"] > *', 19 'nav a', 20 'aside a', 21 '[role="listbox"] [role="option"]', 22 ]; 23 24 for (const sel of selectors) { 25 const nodes = document.querySelectorAll(sel); 26 if (nodes.length > 0) { 27 nodes.forEach((n, i) => { 28 const text = (n.textContent || '').trim().substring(0, 100); 29 if (text) results.push({ Index: i + 1, Title: text }); 30 }); 31 break; 32 } 33 } 34 35 return results; 36 })() 37 `); 38 if (items.length === 0) { 39 return [{ Index: 0, Title: 'No history found. Ensure the sidebar is visible.' }]; 40 } 41 const dateHeaders = /^(today|yesterday|last week|last month|last year|this week|this month|older|previous \d+ days|\d+ days ago)$/i; 42 const numericOnly = /^[\d\s]+$/; 43 const modelPath = /^[\w.-]+\/[\w.-]/; 44 const seen = new Set(); 45 const deduped = items.filter((item) => { 46 const t = item.Title.trim(); 47 if (dateHeaders.test(t)) 48 return false; 49 if (numericOnly.test(t)) 50 return false; 51 if (modelPath.test(t)) 52 return false; 53 if (seen.has(t)) 54 return false; 55 seen.add(t); 56 return true; 57 }).map((item, i) => ({ Index: i + 1, Title: item.Title })); 58 return deduped; 59 }, 60 });