ask.js
1 import { cli, Strategy } from '@jackwener/opencli/registry'; 2 import { SelectorError } from '@jackwener/opencli/errors'; 3 export const askCommand = cli({ 4 site: 'codex', 5 name: 'ask', 6 description: 'Send a prompt and wait for the AI response (send + wait + read)', 7 domain: 'localhost', 8 strategy: Strategy.UI, 9 browser: true, 10 args: [ 11 { name: 'text', required: true, positional: true, help: 'Prompt to send' }, 12 { name: 'timeout', required: false, help: 'Max seconds to wait for response (default: 60)', default: '60' }, 13 ], 14 columns: ['Role', 'Text'], 15 func: async (page, kwargs) => { 16 const text = kwargs.text; 17 const timeout = parseInt(kwargs.timeout, 10) || 60; 18 // Snapshot the current content length before sending 19 const beforeLen = await page.evaluate(` 20 (function() { 21 const turns = document.querySelectorAll('[data-content-search-turn-key]'); 22 return turns.length; 23 })() 24 `); 25 // Inject and send 26 const injected = await page.evaluate(` 27 (function(text) { 28 const editables = Array.from(document.querySelectorAll('[contenteditable="true"]')); 29 const composer = editables.length > 0 ? editables[editables.length - 1] : document.querySelector('textarea'); 30 if (!composer) return false; 31 composer.focus(); 32 document.execCommand('insertText', false, text); 33 return true; 34 })(${JSON.stringify(text)}) 35 `); 36 if (!injected) 37 throw new SelectorError('Codex input element'); 38 await page.wait(0.5); 39 await page.pressKey('Enter'); 40 // Poll for new content 41 const pollInterval = 3; 42 const maxPolls = Math.ceil(timeout / pollInterval); 43 let response = ''; 44 for (let i = 0; i < maxPolls; i++) { 45 await page.wait(pollInterval); 46 const result = await page.evaluate(` 47 (function(prevLen) { 48 const turns = document.querySelectorAll('[data-content-search-turn-key]'); 49 if (turns.length <= prevLen) return null; 50 const lastTurn = turns[turns.length - 1]; 51 const text = lastTurn.innerText || lastTurn.textContent; 52 return text ? text.trim() : null; 53 })(${beforeLen}) 54 `); 55 if (result) { 56 response = result; 57 break; 58 } 59 } 60 if (!response) { 61 return [ 62 { Role: 'User', Text: text }, 63 { Role: 'System', Text: `No response within ${timeout}s. The agent may still be working.` }, 64 ]; 65 } 66 return [ 67 { Role: 'User', Text: text }, 68 { Role: 'Assistant', Text: response }, 69 ]; 70 }, 71 });