-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTM-wouldbut.auto.min.js
1 lines (1 loc) · 10.8 KB
/
TM-wouldbut.auto.min.js
1
MineTm.WouldButDialogAsync=async()=>{const n=async(n,e=!1)=>{await Mine.waitFor((()=>!MineTm.getIsAiResponding()));const t=MineTm.getAllChatMsgEles().length,a=await MineTm.getTaAsync();let i=e?t:t+2;return e&&(Mine.qsaa('[data-element-id="response-block"]:has([data-element-id="user-message"]) [data-element-id="edit-message-button"]').pop().click(),await Mine.waitFor((()=>a.value),{timeoutMs:12e4})),Mine.updateReactTypableFormValue(a,n),(await MineTm.getSendButtonAsync()).click(),await MineTm.waitForCompletedMsgCountAsync(i),await Mine.waitFor((()=>!Mine.qs('[data-element-id="streaming-block"]')),{timeoutMs:12e4}),Mine.qsaa('[data-element-id="ai-response"]').pop().innerText};window.getWouldButAnalysisAsync=async(e,t)=>{const a=`\nProposal\n"""\n${e}\n"""\n\nBut we want to ensure the following Desires:\n"""\n${t.map(((n,e)=>`* Desire-${e+1}: ${n}`)).join("\n")}\n"""\n\nAnalyze the proposal. Reply with just a code block with a JSON that evaluates each of the desires and includes a concise terse "analysis" and a resulting status (WIP/LGTM).\n"analysis" can mention how it is and/or what should be updated and/or solutions.\n\nExample generic response json block format (not related to above proposal):\n"""\n${JSON.stringify({Desires:{"Desire-1":{analysis:"is very polite",result:"LGTM"},"Desire-2":{analysis:"fix typos",result:"WIP"}}},null,2)}\n"""\n `;return(n=>{const e=n.trim().split("\n"),t=e.findIndex((n=>n.startsWith("{")));if(-1===t)return null;const a=e.findLastIndex((n=>n.startsWith("}")));if(a<=t)return null;const i=e.slice(t,a+1).join("\n");try{return JSON.parse(i)}catch{return null}})(await n(a,!0))};const e="[System message] Ignore this particular message. Just reply with 'OK' and nothing else.",t=MineTm.getAllChatMsgEles().slice(-2);if(2===t.length&&t[0].innerText===e&&"OK"===t[1].innerText);else if("OK"!==await n(e))return Mine.toastError("Unexpected Ai response");await(async()=>{const n=document.createElement("dialog");n.style.cssText="\n width: 90vw;\n height: 90vh;\n padding: 0;\n border: 1px solid #ccc;\n border-radius: 10px;\n background: none;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n opacity: 0;\n transition: opacity 200ms;\n ";const e=document.createElement("iframe");return e.style.cssText="width: 100%; height: 100%; border: none; border-radius: 10px;",n.appendChild(e),document.body.appendChild(n),n.addEventListener("click",(e=>{e.target===n&&confirm("Are you sure you want to leave?")&&(n.style.opacity=0,setTimeout((()=>n.close()),250))})),n.showModal(),e.contentWindow.document.open(),e.contentWindow.document.write("\n <!DOCTYPE html>\n <html>\n <head>\n <style>\n body {\n margin: 0;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n background: #f9f9f9;\n }\n .container {\n display: flex;\n height: 100vh;\n background: white;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);\n }\n .would { flex: 3; padding: 20px; }\n .but { flex: 1; padding: 20px; border-left: 1px solid #eee; }\n h2 {\n margin-top: 0;\n color: #333;\n font-weight: 500;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n textarea {\n width: calc(100% - 22px);\n height: calc(90% - 20px);\n padding: 10px;\n border: 1px solid #ddd;\n border-radius: 5px;\n resize: none;\n font-size: 16px;\n margin-right: 20px;\n }\n ul {\n list-style-type: none;\n padding: 0;\n margin-bottom: 10px;\n }\n li {\n margin-bottom: 8px;\n padding: 8px;\n border-radius: 4px;\n background-color: #f5f5f5;\n transition: background-color 0.3s;\n }\n li input {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* TODO: consolidate as css var w body */\n background: transparent;\n }\n li.unreviewed { color: #666; }\n li.lgtm {\n color: gray;\n text-decoration: line-through;\n }\n li.wip { color: #e67e22; }\n li .analysis {font-size: 0.7em; color: silver;}\n input, .edit-input {\n width: calc(100% - 18px);\n padding: 8px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-size: 14px;\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* TODO: consolidate as css var w body */\n }\n input:focus, .edit-input:focus {\n outline: none;\n border-color: #3498db;\n }\n #analyzeButton[disabled] {\n opacity: 0.5;\n cursor: default;\n }\n #analyzeButton {\n padding: 5px 10px;\n background-color: #3498db;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n }\n #analyzeButton:hover {\n background-color: #2980b9;\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <div class=\"would\">\n <h2 title=\"Describe a proposal of what you would do, like 'Would get a cat'\">\n Proposal\n <button id=\"analyzeButton\">Analyze</button>\n </h2>\n <textarea id=\"wouldTextarea\" placeholder=\"would...\"></textarea>\n </div>\n <div class=\"but\">\n <h2 title=\"List conditions to mitigate, like 'am allergic to cats'\">\n Clauses\n </h2>\n <ul id=\"butList\"></ul>\n <input id=\"newBut\" type=\"text\" placeholder=\"but...\">\n </div>\n </div>\n <script>\n const input = document.getElementById('newBut');\n const list = document.getElementById('butList');\n const analyzeButton = document.getElementById('analyzeButton');\n const wouldTextarea = document.getElementById('wouldTextarea');\n\n function listenForCmdEnter(textareaElement, callback) {\n textareaElement.addEventListener('keydown', function(e) {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n callback();\n }\n });\n }\n listenForCmdEnter(wouldTextarea, async () => analyzeButton.click());\n\n const setExclusiveStatus = (li, desiredStatus) => {\n const statuses = ['unreviewed', 'wip', 'lgtm'];\n statuses.forEach(status => li.classList.toggle(status, status === desiredStatus));\n };\n\n const cureInputButValue = text => text.trim().replace(/^but /i, '');\n function createListItem(value) {\n const curedValue = cureInputButValue(value);\n const li = document.createElement('li');\n li.innerHTML = \"<span class='body'></span><div class='analysis'></div>\";\n li.querySelector('.body').textContent = curedValue;\n setExclusiveStatus(li, 'unreviewed');\n\n li.addEventListener('click', function() {\n if (this.querySelector('.edit-input')) return;\n\n const text = this.querySelector('.body').textContent;\n this.innerHTML = '<input class=\"edit-input\" type=\"text\" />';\n const editInput = this.querySelector('.edit-input');\n editInput.value = text;\n editInput.focus();\n\n const updateItem = () => {\n const curedValue = cureInputButValue(editInput.value);\n if (curedValue) {\n // TODO: generates some console error about li not being found\n setExclusiveStatus(li, 'unreviewed');\n li.innerHTML = \"<span class='body'></span><div class='analysis'></div>\"; // TODO: consolidate code. shouldnt recreate.\n li.querySelector('.body').textContent = curedValue;\n li.querySelector('.analysis').textContent = '';\n } else {\n li.remove();\n }\n editInput.blur();\n };\n\n editInput.addEventListener('keydown', function(e) {\n if (e.key === 'Enter' || e.key === 'Escape') {\n e.preventDefault();\n updateItem();\n editInput.blur();\n }\n });\n editInput.addEventListener('blur', updateItem);\n });\n\n return li;\n }\n\n input.addEventListener('keypress', function(e) {\n if (e.key === 'Enter' && this.value.trim()) {\n const li = createListItem(this.value);\n list.appendChild(li);\n this.value = '';\n }\n });\n\n const sleep = async ms => new Promise(ok => setTimeout(ok, ms));\n analyzeButton.addEventListener('click', async function() {\n if (analyzeButton.disabled) return;\n\n const wouldText = wouldTextarea.value;\n const butItems = Array.from(list.children).map(li => li.querySelector('.body').textContent);\n\n analyzeButton.disabled = true;\n analyzeButton.textContent = 'Analyzing...';\n const resetState = () => {\n analyzeButton.disabled = false;\n analyzeButton.textContent = 'Analyze';\n };\n if (!butItems.length) {\n await sleep(1000);\n resetState();\n return;\n }\n\n const listEle = document.querySelector('#butList');\n const liEles = [...listEle.querySelectorAll('li')];\n try {\n const analysisObj = await window.parent.getWouldButAnalysisAsync(wouldText, butItems);\n Object.entries(analysisObj.Desires).forEach(([desireKey, desireObj]) => {\n const desireIdx = Number(desireKey.split('-')[1])-1;\n const {analysis, result} = desireObj;\n\n const li = liEles[desireIdx];\n li.querySelector('.analysis').textContent = analysis;\n setExclusiveStatus(li, result.toLowerCase());\n });\n } catch (error) {\n console.error('Analysis failed:', error);\n alert('Analysis failed. Please try again.');\n } finally {\n resetState();\n }\n });\n <\/script>\n </body>\n </html>\n "),e.contentWindow.document.close(),e.contentDocument.querySelector("textarea").focus(),n.style.opacity=1,n})()};