openmagic 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var OpenMagicToolbar=(()=>{var I=`
2
+ "use strict";var OpenMagicToolbar=(()=>{var Q=`
3
3
  :host {
4
4
  all: initial;
5
5
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
@@ -263,55 +263,67 @@
263
263
  font-family: 'SF Mono', 'Fira Code', Consolas, monospace;
264
264
  font-size: 10px; color: #555; max-height: 60px; overflow-y: auto; margin-bottom: 6px;
265
265
  }
266
- `;var m=null,u=new Map,he=[],O=[],x=!1,G=!1,_=null;function R(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function A(e,o){return G=!0,new Promise((t,n)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,n(new Error("Handshake timeout")),m?.close())},1e4);try{let r=window.location.hostname||"127.0.0.1";m=new WebSocket(`ws://${r}:${e}/__openmagic__/ws`),m.onopen=()=>{let l=R();m.send(JSON.stringify({id:l,type:"handshake",payload:{token:o}})),u.set(l,c=>{if(c.type==="handshake.ok"){clearTimeout(i),x=!0;for(let b of O)m?.send(b);O=[],s||(s=!0,t())}else c.type==="error"&&(clearTimeout(i),s||(s=!0,n(new Error(c.payload?.message||"Handshake failed"))))})},m.onmessage=l=>{try{let c=JSON.parse(l.data);c.id&&u.has(c.id)&&(u.get(c.id)(c),(c.type==="llm.done"||c.type==="llm.error"||!c.type.startsWith("llm."))&&u.delete(c.id));for(let b of he)b(c)}catch{}},m.onclose=()=>{let l=x;if(x=!1,!l&&!s){clearTimeout(i),s=!0,n(new Error("WebSocket closed before handshake"));return}l&&G&&!_&&(_=setTimeout(()=>{_=null,A(e,o).catch(()=>{})},2e3))},m.onerror=()=>{!x&&!s&&(clearTimeout(i),s=!0,n(new Error("WebSocket connection failed")))}}catch(r){clearTimeout(i),s||(s=!0,n(r))}})}function K(e){let o=JSON.stringify(e);m&&m.readyState===WebSocket.OPEN&&x?m.send(o):O.push(o)}function v(e,o){return new Promise((t,n)=>{let s=R(),i=setTimeout(()=>{u.delete(s),n(new Error("Request timeout"))},3e4);u.set(s,r=>{clearTimeout(i),r.type==="error"?n(new Error(r.payload?.message||"Unknown error")):t(r)}),K({id:s,type:e,payload:o})})}function j(e,o,t){return new Promise((n,s)=>{let i=R(),r=setTimeout(()=>{u.delete(i),s(new Error("Stream timeout"))},12e4);u.set(i,l=>{l.type==="llm.chunk"?t(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(r),u.delete(i),n(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(r),u.delete(i),s(new Error(l.payload?.message||"Stream error")))}),K({id:i,type:e,payload:o})})}function V(){return x}var be=["display","position","width","height","margin","padding","color","background-color","background","font-size","font-weight","font-family","border","border-radius","box-shadow","flex-direction","justify-content","align-items","gap","grid-template-columns","grid-template-rows","overflow","opacity","z-index","text-align","line-height","letter-spacing"];function F(e){let o=window.getComputedStyle(e),t={};for(let s of be)t[s]=o.getPropertyValue(s);let n=e.getBoundingClientRect();return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().slice(0,200),outerHTML:ye(e),cssSelector:xe(e),xpath:ve(e),computedStyles:t,rect:{x:n.x,y:n.y,width:n.width,height:n.height}}}function ye(e){let o=e.cloneNode(!0);o.querySelectorAll("script, style, svg").forEach(s=>s.remove());let n=o.outerHTML;if(n.length>2e3){let s=e.tagName.toLowerCase(),i=Array.from(e.attributes).map(l=>`${l.name}="${l.value}"`).join(" "),r=Array.from(e.children).slice(0,5).map(l=>`<${l.tagName.toLowerCase()} .../>`).join(`
267
- `);n=`<${s} ${i}>
268
- ${r}
266
+
267
+ /* \u2500\u2500 Diff Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
268
+ .om-diff-card { background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.06); border-radius: 8px; padding: 8px 10px; margin: 4px 0; font-size: 12px; }
269
+ .om-diff-file { color: #a29bfe; font-size: 11px; font-weight: 600; margin-bottom: 6px; font-family: 'SF Mono', Consolas, monospace; }
270
+ .om-diff-removed { background: rgba(233,69,96,0.08); color: #fab1a0; padding: 4px 8px; border-radius: 4px; font-family: 'SF Mono', Consolas, monospace; font-size: 11px; white-space: pre-wrap; word-break: break-all; margin-bottom: 4px; }
271
+ .om-diff-added { background: rgba(0,184,148,0.08); color: #55efc4; padding: 4px 8px; border-radius: 4px; font-family: 'SF Mono', Consolas, monospace; font-size: 11px; white-space: pre-wrap; word-break: break-all; margin-bottom: 6px; }
272
+ .om-diff-actions { display: flex; gap: 6px; }
273
+ .om-btn-sm { padding: 4px 10px; font-size: 11px; border-radius: 6px; }
274
+ .om-btn-secondary { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08); color: #888; cursor: pointer; font-family: inherit; }
275
+ .om-btn-secondary:hover { background: rgba(255,255,255,0.08); color: #ccc; }
276
+ .om-diff-applied { opacity: 0.5; }
277
+ .om-diff-applied .om-diff-actions { display: none; }
278
+ `;var f=null,b=new Map,C=[],U=[],M=!1,Z=!1,z=null;function j(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function G(e,t){return Z=!0,new Promise((o,a)=>{let r=!1,s=setTimeout(()=>{r||(r=!0,a(new Error("Handshake timeout")),f?.close())},1e4);try{let i=window.location.hostname||"127.0.0.1";f=new WebSocket(`ws://${i}:${e}/__openmagic__/ws`),f.onopen=()=>{let l=j();f.send(JSON.stringify({id:l,type:"handshake",payload:{token:t}})),b.set(l,c=>{if(c.type==="handshake.ok"){clearTimeout(s),M=!0;for(let g of U)f?.send(g);U=[],r||(r=!0,o())}else c.type==="error"&&(clearTimeout(s),r||(r=!0,a(new Error(c.payload?.message||"Handshake failed"))))})},f.onmessage=l=>{try{let c=JSON.parse(l.data);c.id&&b.has(c.id)&&(b.get(c.id)(c),(c.type==="llm.done"||c.type==="llm.error"||!c.type.startsWith("llm."))&&b.delete(c.id));for(let g of C)g(c)}catch{}},f.onclose=()=>{let l=M;if(M=!1,!l&&!r){clearTimeout(s),r=!0,a(new Error("WebSocket closed before handshake"));return}l&&Z&&!z&&(z=setTimeout(()=>{z=null,G(e,t).then(()=>{for(let c of C)c({type:"reconnected",payload:{}})}).catch(()=>{})},2e3))},f.onerror=()=>{!M&&!r&&(clearTimeout(s),r=!0,a(new Error("WebSocket connection failed")))}}catch(i){clearTimeout(s),r||(r=!0,a(i))}})}function ee(e){let t=JSON.stringify(e);f&&f.readyState===WebSocket.OPEN&&M?f.send(t):U.push(t)}function S(e,t){return new Promise((o,a)=>{let r=j(),s=setTimeout(()=>{b.delete(r),a(new Error("Request timeout"))},3e4);b.set(r,i=>{clearTimeout(s),i.type==="error"?a(new Error(i.payload?.message||"Unknown error")):o(i)}),ee({id:r,type:e,payload:t})})}function te(e,t,o){return new Promise((a,r)=>{let s=j(),i=setTimeout(()=>{b.delete(s),r(new Error("Stream timeout"))},12e4);b.set(s,l=>{l.type==="llm.chunk"?o(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(i),b.delete(s),a(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(i),b.delete(s),r(new Error(l.payload?.message||"Stream error")))}),ee({id:s,type:e,payload:t})})}function oe(e){return C.push(e),()=>{C=C.filter(t=>t!==e)}}function ne(){return M}var Ee=["display","position","width","height","margin","padding","color","background-color","background","font-size","font-weight","font-family","border","border-radius","box-shadow","flex-direction","justify-content","align-items","gap","grid-template-columns","grid-template-rows","overflow","opacity","z-index","text-align","line-height","letter-spacing"];function ae(e){let t=window.getComputedStyle(e),o={};for(let r of Ee)o[r]=t.getPropertyValue(r);let a=e.getBoundingClientRect();return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().slice(0,200),outerHTML:Me(e),cssSelector:Le(e),xpath:Te(e),computedStyles:o,rect:{x:a.x,y:a.y,width:a.width,height:a.height}}}function Me(e){let t=e.cloneNode(!0);t.querySelectorAll("script, style, svg").forEach(r=>r.remove());let a=t.outerHTML;if(a.length>2e3){let r=e.tagName.toLowerCase(),s=Array.from(e.attributes).map(l=>`${l.name}="${l.value}"`).join(" "),i=Array.from(e.children).slice(0,5).map(l=>`<${l.tagName.toLowerCase()} .../>`).join(`
279
+ `);a=`<${r} ${s}>
280
+ ${i}
269
281
  ${e.children.length>5?`<!-- +${e.children.length-5} more children -->`:""}
270
- </${s}>`}return n}function xe(e){if(e.id)return`#${CSS.escape(e.id)}`;let o=[],t=e;for(;t&&t!==document.body;){let n=t.tagName.toLowerCase();if(t.id){o.unshift(`#${CSS.escape(t.id)}`);break}if(t.className&&typeof t.className=="string"){let i=t.className.trim().split(/\s+/).filter(r=>!r.startsWith("__")&&r.length<30).slice(0,2).map(r=>CSS.escape(r));i.length>0&&(n+="."+i.join("."))}let s=t.parentElement;if(s){let i=Array.from(s.children).filter(r=>r.tagName===t.tagName);if(i.length>1){let r=i.indexOf(t)+1;n+=`:nth-of-type(${r})`}}o.unshift(n),t=t.parentElement}return o.join(" > ")}function ve(e){let o=[],t=e;for(;t&&t!==document;){if(t.nodeType===Node.ELEMENT_NODE){let n=t,s=1,i=n.previousElementSibling;for(;i;)i.tagName===n.tagName&&s++,i=i.previousElementSibling;o.unshift(`${n.tagName.toLowerCase()}[${s}]`)}t=t.parentNode}return"/"+o.join("/")}var p=null;function W(e){p||(p=document.createElement("div"),p.style.cssText=`
282
+ </${r}>`}return a}function Le(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=[],o=e;for(;o&&o!==document.body;){let a=o.tagName.toLowerCase();if(o.id){t.unshift(`#${CSS.escape(o.id)}`);break}if(o.className&&typeof o.className=="string"){let s=o.className.trim().split(/\s+/).filter(i=>!i.startsWith("__")&&i.length<30).slice(0,2).map(i=>CSS.escape(i));s.length>0&&(a+="."+s.join("."))}let r=o.parentElement;if(r){let s=Array.from(r.children).filter(i=>i.tagName===o.tagName);if(s.length>1){let i=s.indexOf(o)+1;a+=`:nth-of-type(${i})`}}t.unshift(a),o=o.parentElement}return t.join(" > ")}function Te(e){let t=[],o=e;for(;o&&o!==document;){if(o.nodeType===Node.ELEMENT_NODE){let a=o,r=1,s=a.previousElementSibling;for(;s;)s.tagName===a.tagName&&r++,s=s.previousElementSibling;t.unshift(`${a.tagName.toLowerCase()}[${r}]`)}o=o.parentNode}return"/"+t.join("/")}var h=null;function se(e){h||(h=document.createElement("div"),h.style.cssText=`
271
283
  position: fixed;
272
284
  pointer-events: none;
273
285
  z-index: 2147483646;
274
286
  border: 2px solid #6c5ce7;
275
287
  background: rgba(108, 92, 231, 0.1);
276
288
  transition: all 0.1s ease;
277
- `,p.dataset.openmagic="highlight",document.body.appendChild(p)),p.style.left=`${e.x}px`,p.style.top=`${e.y}px`,p.style.width=`${e.width}px`,p.style.height=`${e.height}px`,p.style.display="block"}function X(){p&&(p.style.display="none")}async function Y(e){try{return e?await ke(e):await we()}catch(o){return console.warn("[OpenMagic] Screenshot capture failed:",o),null}}async function we(){let e=document.createElement("canvas"),o=window.devicePixelRatio||1;e.width=window.innerWidth*o,e.height=window.innerHeight*o;let t=e.getContext("2d");t.scale(o,o);try{let n=await J(document.body),s=await Z(n,window.innerWidth,window.innerHeight);return t.drawImage(s,0,0),e.toDataURL("image/png")}catch{return null}}async function ke(e){let o=e.getBoundingClientRect(),t=document.createElement("canvas"),n=window.devicePixelRatio||1;t.width=o.width*n,t.height=o.height*n;let s=t.getContext("2d");s.scale(n,n);try{let i=await J(e),r=await Z(i,o.width,o.height);return s.drawImage(r,0,0),t.toDataURL("image/png")}catch{return null}}function J(e){return new Promise(o=>{let t=e.cloneNode(!0);Q(e,t);let n=e.getBoundingClientRect(),s=n.width,i=n.height,r=`
278
- <svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${i}">
289
+ `,h.dataset.openmagic="highlight",document.body.appendChild(h)),h.style.left=`${e.x}px`,h.style.top=`${e.y}px`,h.style.width=`${e.width}px`,h.style.height=`${e.height}px`,h.style.display="block"}function re(){h&&(h.style.display="none")}async function ie(e){try{return e?await $e(e):await Ce()}catch(t){return console.warn("[OpenMagic] Screenshot capture failed:",t),null}}async function Ce(){let e=document.createElement("canvas"),t=window.devicePixelRatio||1;e.width=window.innerWidth*t,e.height=window.innerHeight*t;let o=e.getContext("2d");o.scale(t,t);try{let a=await le(document.body),r=await de(a,window.innerWidth,window.innerHeight);return o.drawImage(r,0,0),e.toDataURL("image/png")}catch{return null}}async function $e(e){let t=e.getBoundingClientRect(),o=document.createElement("canvas"),a=window.devicePixelRatio||1;o.width=t.width*a,o.height=t.height*a;let r=o.getContext("2d");r.scale(a,a);try{let s=await le(e),i=await de(s,t.width,t.height);return r.drawImage(i,0,0),o.toDataURL("image/png")}catch{return null}}function le(e){return new Promise(t=>{let o=e.cloneNode(!0);ce(e,o);let a=e.getBoundingClientRect(),r=a.width,s=a.height,i=`
290
+ <svg xmlns="http://www.w3.org/2000/svg" width="${r}" height="${s}">
279
291
  <foreignObject width="100%" height="100%">
280
- <div xmlns="http://www.w3.org/1999/xhtml" style="width:${s}px;height:${i}px;overflow:hidden;">
281
- ${t.outerHTML}
292
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width:${r}px;height:${s}px;overflow:hidden;">
293
+ ${o.outerHTML}
282
294
  </div>
283
295
  </foreignObject>
284
- </svg>`;o(r)})}function Q(e,o){let t=window.getComputedStyle(e),n="";for(let r=0;r<t.length;r++){let l=t[r];n+=`${l}:${t.getPropertyValue(l)};`}o.style.cssText=n;let s=e.children,i=o.children;for(let r=0;r<s.length&&r<i.length;r++)Q(s[r],i[r])}function Z(e,o,t){return new Promise((n,s)=>{let i=new Image,r=new Blob([e],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(r);i.onload=()=>{URL.revokeObjectURL(l),n(i)},i.onerror=()=>{URL.revokeObjectURL(l),s(new Error("Failed to load SVG image"))},i.width=o,i.height=t,i.src=l})}var T=[];var ee=!1;function oe(){if(ee)return;ee=!0;let e=window.fetch;window.fetch=async function(...n){let s=new Request(...n),i={method:s.method,url:s.url,timestamp:Date.now()};try{let r=await e.apply(this,n);return i.status=r.status,i.duration=Date.now()-i.timestamp,q(i),r}catch(r){throw i.status=0,i.duration=Date.now()-i.timestamp,q(i),r}};let o=XMLHttpRequest.prototype.open,t=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,s,...i){return this.__om_method=n,this.__om_url=s,this.__om_start=Date.now(),o.apply(this,[n,s,...i])},XMLHttpRequest.prototype.send=function(...n){return this.addEventListener("loadend",()=>{q({method:this.__om_method||"GET",url:this.__om_url||"",status:this.status,duration:Date.now()-(this.__om_start||Date.now()),timestamp:this.__om_start||Date.now()})}),t.apply(this,n)}}function q(e){e.url.includes("__openmagic__")||(T.push(e),T.length>50&&T.shift())}function Se(){return[...T]}var C=[],Le=100,te=!1;function ne(){if(te)return;te=!0;let e=["log","warn","error","info","debug"];for(let o of e){let t=console[o];console[o]=function(...n){C.push({level:o,args:n.map(s=>{try{return typeof s=="object"?JSON.stringify(s).slice(0,500):String(s)}catch{return String(s)}}),timestamp:Date.now()}),C.length>Le&&C.shift(),t.apply(console,n)}}}function Ee(){return[...C]}function ae(e,o){return{selectedElement:e?{tagName:e.tagName,id:e.id,className:e.className,textContent:e.textContent,outerHTML:e.outerHTML,cssSelector:e.cssSelector,computedStyles:e.computedStyles}:void 0,screenshot:o||void 0,networkLogs:Se().map(t=>({method:t.method,url:t.url,status:t.status,duration:t.duration,timestamp:t.timestamp})),consoleLogs:Ee().map(t=>({level:t.level,args:t.args,timestamp:t.timestamp}))}}var d={sparkle:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .962L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/></svg>',crosshair:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="22" y1="12" x2="18" y2="12"/><line x1="6" y1="12" x2="2" y2="12"/><line x1="12" y1="6" x2="12" y2="2"/><line x1="12" y1="22" x2="12" y2="18"/></svg>',camera:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></svg>',chat:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',settings:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>',send:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>',x:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',externalLink:'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>',check:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg>',grip:'<svg width="7" height="14" viewBox="0 0 8 14" fill="currentColor"><circle cx="2" cy="2" r="1.2"/><circle cx="6" cy="2" r="1.2"/><circle cx="2" cy="7" r="1.2"/><circle cx="6" cy="7" r="1.2"/><circle cx="2" cy="12" r="1.2"/><circle cx="6" cy="12" r="1.2"/></svg>'},$={openai:{name:"OpenAI",keyUrl:"https://platform.openai.com/api-keys",keyPlaceholder:"sk-...",models:[{id:"gpt-5.4",name:"GPT-5.4"},{id:"gpt-5.4-mini",name:"GPT-5.4 Mini"},{id:"gpt-5.2",name:"GPT-5.2 Thinking"},{id:"o3",name:"o3"},{id:"o4-mini",name:"o4-mini"},{id:"gpt-4.1",name:"GPT-4.1"},{id:"gpt-4.1-mini",name:"GPT-4.1 Mini"}]},anthropic:{name:"Anthropic",keyUrl:"https://console.anthropic.com/settings/keys",keyPlaceholder:"sk-ant-...",models:[{id:"claude-opus-4-6",name:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",name:"Claude Sonnet 4.6"},{id:"claude-haiku-4-5-20251001",name:"Claude Haiku 4.5"}]},google:{name:"Google Gemini",keyUrl:"https://aistudio.google.com/apikey",keyPlaceholder:"AIza...",models:[{id:"gemini-3.1-pro-preview",name:"Gemini 3.1 Pro"},{id:"gemini-3-flash-preview",name:"Gemini 3 Flash"},{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro"},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash"}]},xai:{name:"xAI (Grok)",keyUrl:"https://console.x.ai/team/default/api-keys",keyPlaceholder:"xai-...",models:[{id:"grok-4.20-0309-reasoning",name:"Grok 4.20 Reasoning"},{id:"grok-4-1-fast-non-reasoning",name:"Grok 4.1 Fast"}]},deepseek:{name:"DeepSeek",keyUrl:"https://platform.deepseek.com/api_keys",keyPlaceholder:"sk-...",models:[{id:"deepseek-chat",name:"DeepSeek V3.2"},{id:"deepseek-reasoner",name:"DeepSeek R1"}]},mistral:{name:"Mistral",keyUrl:"https://console.mistral.ai/api-keys",keyPlaceholder:"...",models:[{id:"mistral-large-3-25-12",name:"Mistral Large 3"},{id:"codestral-2508",name:"Codestral"},{id:"devstral-2-25-12",name:"Devstral 2"}]},groq:{name:"Groq",keyUrl:"https://console.groq.com/keys",keyPlaceholder:"gsk_...",models:[{id:"meta-llama/llama-4-scout-17b-16e-instruct",name:"Llama 4 Scout"},{id:"llama-3.3-70b-versatile",name:"Llama 3.3 70B"}]},minimax:{name:"MiniMax",keyUrl:"https://platform.minimax.chat/user-center/basic-information/interface-key",keyPlaceholder:"MiniMax key...",models:[{id:"MiniMax-M2.7",name:"MiniMax M2.7"},{id:"MiniMax-M2.5",name:"MiniMax M2.5"}]},moonshot:{name:"Kimi (Moonshot)",keyUrl:"https://platform.moonshot.cn/console/api-keys",keyPlaceholder:"Moonshot key...",models:[{id:"kimi-k2.5",name:"Kimi K2.5"},{id:"kimi-k2-thinking",name:"Kimi K2 Thinking"}]},qwen:{name:"Qwen (Alibaba)",keyUrl:"https://dashscope.console.aliyun.com/apiKey",keyPlaceholder:"DashScope key...",models:[{id:"qwen3.5-plus",name:"Qwen 3.5 Plus"},{id:"qwen-max",name:"Qwen Max"}]},zhipu:{name:"Zhipu AI (GLM)",keyUrl:"https://open.bigmodel.cn/usercenter/apikeys",keyPlaceholder:"Zhipu key...",models:[{id:"glm-5",name:"GLM-5"},{id:"glm-4.7",name:"GLM-4.7"}]},doubao:{name:"Doubao (ByteDance)",keyUrl:"https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey",keyPlaceholder:"Volcano key...",models:[{id:"doubao-seed-2-0-pro",name:"Doubao Seed 2.0 Pro"},{id:"doubao-seed-2-0-code",name:"Doubao Seed 2.0 Code"}]},ollama:{name:"Ollama (Local)",keyPlaceholder:"not required",local:!0,models:[]},openrouter:{name:"OpenRouter",keyUrl:"https://openrouter.ai/settings/keys",keyPlaceholder:"sk-or-...",models:[]}},ce="0.11.0",a={connected:!1,panelOpen:!1,activePanel:"",selecting:!1,selectedElement:null,screenshot:null,messages:[],streaming:!1,streamContent:"",provider:"",model:"",hasApiKey:!1,roots:[],updateAvailable:!1,latestVersion:"",saveStatus:""},h,f,k,de,z,g;function se(){if(document.querySelector("openmagic-toolbar"))return;let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",h=e.attachShadow({mode:"closed"});let o=document.createElement("style");o.textContent=I,h.appendChild(o);let t=document.createElement("div");h.appendChild(t),t.innerHTML=Me(),f=t.querySelector(".om-toolbar"),k=t.querySelector(".om-prompt-input"),de=t.querySelector(".om-prompt-context"),z=t.querySelector(".om-panel"),g=t.querySelector(".om-panel-body"),document.body.appendChild(e),Te(t),Oe(),oe(),ne(),Re();let n=window.__OPENMAGIC_TOKEN__,s=parseInt(window.location.port,10)||(window.location.protocol==="https:"?443:80);n&&A(s,n).then(()=>(a.connected=!0,ie(),v("config.get"))).then(i=>{a.provider=i.payload?.provider||"",a.model=i.payload?.model||"",a.hasApiKey=i.payload?.hasApiKey||!1,a.roots=i.payload?.roots||[],(!a.provider||!a.hasApiKey)&&S("settings"),M()}).catch(()=>{a.connected=!1,ie()})}function Me(){return`
296
+ </svg>`;t(i)})}function ce(e,t){let o=window.getComputedStyle(e),a="";for(let i=0;i<o.length;i++){let l=o[i];a+=`${l}:${o.getPropertyValue(l)};`}t.style.cssText=a;let r=e.children,s=t.children;for(let i=0;i<r.length&&i<s.length;i++)ce(r[i],s[i])}function de(e,t,o){return new Promise((a,r)=>{let s=new Image,i=new Blob([e],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(i);s.onload=()=>{URL.revokeObjectURL(l),a(s)},s.onerror=()=>{URL.revokeObjectURL(l),r(new Error("Failed to load SVG image"))},s.width=t,s.height=o,s.src=l})}var D=[];var pe=!1;function ue(){if(pe)return;pe=!0;let e=window.fetch;window.fetch=async function(...a){let r=new Request(...a),s={method:r.method,url:r.url,timestamp:Date.now()};try{let i=await e.apply(this,a);return s.status=i.status,s.duration=Date.now()-s.timestamp,K(s),i}catch(i){throw s.status=0,s.duration=Date.now()-s.timestamp,K(s),i}};let t=XMLHttpRequest.prototype.open,o=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(a,r,...s){return this.__om_method=a,this.__om_url=r,this.__om_start=Date.now(),t.apply(this,[a,r,...s])},XMLHttpRequest.prototype.send=function(...a){return this.addEventListener("loadend",()=>{K({method:this.__om_method||"GET",url:this.__om_url||"",status:this.status,duration:Date.now()-(this.__om_start||Date.now()),timestamp:this.__om_start||Date.now()})}),o.apply(this,a)}}function K(e){e.url.includes("__openmagic__")||(D.push(e),D.length>50&&D.shift())}function He(){return[...D]}var A=[],_e=100,me=!1;function ge(){if(me)return;me=!0;let e=["log","warn","error","info","debug"];for(let t of e){let o=console[t];console[t]=function(...a){A.push({level:t,args:a.map(r=>{try{return typeof r=="object"?JSON.stringify(r).slice(0,500):String(r)}catch{return String(r)}}),timestamp:Date.now()}),A.length>_e&&A.shift(),o.apply(console,a)}}}function Pe(){return[...A]}function he(e,t){return{selectedElement:e?{tagName:e.tagName,id:e.id,className:e.className,textContent:e.textContent,outerHTML:e.outerHTML,cssSelector:e.cssSelector,computedStyles:e.computedStyles}:void 0,screenshot:t||void 0,networkLogs:He().map(o=>({method:o.method,url:o.url,status:o.status,duration:o.duration,timestamp:o.timestamp})),consoleLogs:Pe().map(o=>({level:o.level,args:o.args,timestamp:o.timestamp}))}}var p={sparkle:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .962L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/></svg>',crosshair:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="22" y1="12" x2="18" y2="12"/><line x1="6" y1="12" x2="2" y2="12"/><line x1="12" y1="6" x2="12" y2="2"/><line x1="12" y1="22" x2="12" y2="18"/></svg>',camera:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></svg>',chat:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',settings:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>',send:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>',x:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',externalLink:'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>',check:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg>',grip:'<svg width="7" height="14" viewBox="0 0 8 14" fill="currentColor"><circle cx="2" cy="2" r="1.2"/><circle cx="6" cy="2" r="1.2"/><circle cx="2" cy="7" r="1.2"/><circle cx="6" cy="7" r="1.2"/><circle cx="2" cy="12" r="1.2"/><circle cx="6" cy="12" r="1.2"/></svg>'},_={openai:{name:"OpenAI",keyUrl:"https://platform.openai.com/api-keys",keyPlaceholder:"sk-...",models:[{id:"gpt-5.4",name:"GPT-5.4"},{id:"gpt-5.4-mini",name:"GPT-5.4 Mini"},{id:"gpt-5.2",name:"GPT-5.2 Thinking"},{id:"o3",name:"o3"},{id:"o4-mini",name:"o4-mini"},{id:"gpt-4.1",name:"GPT-4.1"},{id:"gpt-4.1-mini",name:"GPT-4.1 Mini"}]},anthropic:{name:"Anthropic",keyUrl:"https://console.anthropic.com/settings/keys",keyPlaceholder:"sk-ant-...",models:[{id:"claude-opus-4-6",name:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",name:"Claude Sonnet 4.6"},{id:"claude-haiku-4-5-20251001",name:"Claude Haiku 4.5"}]},google:{name:"Google Gemini",keyUrl:"https://aistudio.google.com/apikey",keyPlaceholder:"AIza...",models:[{id:"gemini-3.1-pro-preview",name:"Gemini 3.1 Pro"},{id:"gemini-3-flash-preview",name:"Gemini 3 Flash"},{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro"},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash"}]},xai:{name:"xAI (Grok)",keyUrl:"https://console.x.ai/team/default/api-keys",keyPlaceholder:"xai-...",models:[{id:"grok-4.20-0309-reasoning",name:"Grok 4.20 Reasoning"},{id:"grok-4-1-fast-non-reasoning",name:"Grok 4.1 Fast"}]},deepseek:{name:"DeepSeek",keyUrl:"https://platform.deepseek.com/api_keys",keyPlaceholder:"sk-...",models:[{id:"deepseek-chat",name:"DeepSeek V3.2"},{id:"deepseek-reasoner",name:"DeepSeek R1"}]},mistral:{name:"Mistral",keyUrl:"https://console.mistral.ai/api-keys",keyPlaceholder:"...",models:[{id:"mistral-large-3-25-12",name:"Mistral Large 3"},{id:"codestral-2508",name:"Codestral"},{id:"devstral-2-25-12",name:"Devstral 2"}]},groq:{name:"Groq",keyUrl:"https://console.groq.com/keys",keyPlaceholder:"gsk_...",models:[{id:"meta-llama/llama-4-scout-17b-16e-instruct",name:"Llama 4 Scout"},{id:"llama-3.3-70b-versatile",name:"Llama 3.3 70B"}]},minimax:{name:"MiniMax",keyUrl:"https://platform.minimax.chat/user-center/basic-information/interface-key",keyPlaceholder:"MiniMax key...",models:[{id:"MiniMax-M2.7",name:"MiniMax M2.7"},{id:"MiniMax-M2.5",name:"MiniMax M2.5"}]},moonshot:{name:"Kimi (Moonshot)",keyUrl:"https://platform.moonshot.cn/console/api-keys",keyPlaceholder:"Moonshot key...",models:[{id:"kimi-k2.5",name:"Kimi K2.5"},{id:"kimi-k2-thinking",name:"Kimi K2 Thinking"}]},qwen:{name:"Qwen (Alibaba)",keyUrl:"https://dashscope.console.aliyun.com/apiKey",keyPlaceholder:"DashScope key...",models:[{id:"qwen3.5-plus",name:"Qwen 3.5 Plus"},{id:"qwen-max",name:"Qwen Max"}]},zhipu:{name:"Zhipu AI (GLM)",keyUrl:"https://open.bigmodel.cn/usercenter/apikeys",keyPlaceholder:"Zhipu key...",models:[{id:"glm-5",name:"GLM-5"},{id:"glm-4.7",name:"GLM-4.7"}]},doubao:{name:"Doubao (ByteDance)",keyUrl:"https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey",keyPlaceholder:"Volcano key...",models:[{id:"doubao-seed-2-0-pro",name:"Doubao Seed 2.0 Pro"},{id:"doubao-seed-2-0-code",name:"Doubao Seed 2.0 Code"}]},ollama:{name:"Ollama (Local)",keyPlaceholder:"not required",local:!0,models:[]},openrouter:{name:"OpenRouter",keyUrl:"https://openrouter.ai/settings/keys",keyPlaceholder:"sk-or-...",models:[]}};function F(e){let t=new TextEncoder().encode(e),o="";for(let a=0;a<t.length;a+=32768)o+=String.fromCharCode(...t.subarray(a,a+32768));return btoa(o)}function V(e){let t=atob(e),o=new Uint8Array(t.length);for(let a=0;a<t.length;a++)o[a]=t.charCodeAt(a);return new TextDecoder().decode(o)}var xe="0.13.0",n={connected:!1,panelOpen:!1,activePanel:"",selecting:!1,selectedElement:null,screenshot:null,messages:[],streaming:!1,streamContent:"",provider:"",model:"",hasApiKey:!1,roots:[],updateAvailable:!1,latestVersion:"",saveStatus:""},w,u,L,ve,J,y;function fe(){if(document.querySelector("openmagic-toolbar"))return;let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",w=e.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=Q,w.appendChild(t);let o=document.createElement("div");w.appendChild(o),o.innerHTML=Ne(),u=o.querySelector(".om-toolbar"),L=o.querySelector(".om-prompt-input"),ve=o.querySelector(".om-prompt-context"),J=o.querySelector(".om-panel"),y=o.querySelector(".om-panel-body"),document.body.appendChild(e),Oe(o),je();try{let i=JSON.parse(localStorage.getItem("__om_pos__")||"");i?.left&&i?.top&&(u.style.left=i.left,u.style.top=i.top,u.style.right="auto",u.style.bottom="auto")}catch{}ue(),ge(),Ge();let r=document.querySelector("script[data-openmagic-token]")?.dataset.openmagicToken||window.__OPENMAGIC_TOKEN__,s=parseInt(window.location.port,10)||(window.location.protocol==="https:"?443:80);r&&G(s,r).then(()=>(n.connected=!0,X(),S("config.get"))).then(i=>{n.provider=i.payload?.provider||"",n.model=i.payload?.model||"",n.hasApiKey=i.payload?.hasApiKey||!1,n.roots=i.payload?.roots||[],(!n.provider||!n.hasApiKey)&&T("settings"),N()}).catch(()=>{n.connected=!1,X()})}function Ne(){return`
285
297
  <div class="om-toolbar">
286
298
  <div class="om-toolbar-header">
287
- <span class="om-grab">${d.grip}</span>
299
+ <span class="om-grab">${p.grip}</span>
288
300
  <span class="om-pill-brand">
289
- <span class="om-pill-icon">${d.sparkle}</span>
301
+ <span class="om-pill-icon">${p.sparkle}</span>
290
302
  <span class="om-pill-text">OpenMagic</span>
291
303
  </span>
292
304
  <span class="om-pill-divider"></span>
293
- <button class="om-pill-btn" data-action="select" title="Select element">${d.crosshair}</button>
294
- <button class="om-pill-btn" data-action="screenshot" title="Screenshot">${d.camera}</button>
305
+ <button class="om-pill-btn" data-action="select" title="Select element">${p.crosshair}</button>
306
+ <button class="om-pill-btn" data-action="screenshot" title="Screenshot">${p.camera}</button>
295
307
  <span class="om-pill-divider"></span>
296
- <button class="om-pill-btn" data-action="chat" title="Chat">${d.chat}</button>
297
- <button class="om-pill-btn" data-action="settings" title="Settings">${d.settings}</button>
308
+ <button class="om-pill-btn" data-action="chat" title="Chat">${p.chat}</button>
309
+ <button class="om-pill-btn" data-action="settings" title="Settings">${p.settings}</button>
298
310
  <span class="om-status-dot disconnected"></span>
299
311
  </div>
300
312
  <div class="om-panel om-hidden">
301
313
  <div class="om-panel-header">
302
314
  <span class="om-panel-title"></span>
303
- <span class="om-panel-version">v${ce}</span>
304
- <button class="om-panel-close" data-action="close-panel">${d.x}</button>
315
+ <span class="om-panel-version">v${xe}</span>
316
+ <button class="om-panel-close" data-action="close-panel">${p.x}</button>
305
317
  </div>
306
318
  <div class="om-panel-body"></div>
307
319
  </div>
308
320
  <div class="om-prompt-row">
309
321
  <div class="om-prompt-context"></div>
310
322
  <input class="om-prompt-input" type="text" placeholder="Describe what to change..." autocomplete="off" />
311
- <button class="om-prompt-send" data-action="prompt-send">${d.send}</button>
323
+ <button class="om-prompt-send" data-action="prompt-send">${p.send}</button>
312
324
  </div>
313
- </div>`}function Te(e){e.addEventListener("click",o=>{let t=o.target.closest("[data-action]");if(!t)return;o.preventDefault(),o.stopPropagation();let n=t.dataset.action;Ce(n,t)}),e.addEventListener("change",o=>{let t=o.target,n=t.dataset.field;n&&(n==="provider"?(a.provider=t.value,a.model="",a.saveStatus="",w()):n==="model"&&(a.model=t.value))}),k.addEventListener("keydown",o=>{o.key==="Enter"&&!o.shiftKey&&(o.preventDefault(),me())})}function Ce(e,o){switch(e){case"select":Ne();break;case"screenshot":_e();break;case"chat":re("chat");break;case"settings":re("settings");break;case"close-panel":pe();break;case"prompt-send":me();break;case"save-settings":Pe();break;case"get-key":{let t=o.dataset.url;t&&window.open(t,"_blank","noopener");break}case"clear-element":a.selectedElement=null,P();break;case"clear-screenshot":a.screenshot=null,P();break}}function ie(){let e=h.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${a.connected?"connected":"disconnected"}`)}function M(){h.querySelectorAll(".om-pill-btn").forEach(e=>{let o=e.dataset.action;e.classList.toggle("active",o===a.activePanel||o==="select"&&a.selecting)})}function P(){let e=[];a.selectedElement&&e.push(`<span class="om-prompt-chip">${a.selectedElement.tagName}${a.selectedElement.id?"#"+a.selectedElement.id:""} <button class="om-prompt-chip-x" data-action="clear-element">${d.x}</button></span>`),a.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${d.x}</button></span>`),de.innerHTML=e.join("")}function S(e){a.panelOpen=!0,a.activePanel=e,z.classList.remove("om-hidden");let o=h.querySelector(".om-panel-title");o&&(o.textContent=e==="settings"?"Settings":"Chat"),w(),M()}function pe(){a.panelOpen=!1,a.activePanel="",z.classList.add("om-hidden"),M()}function re(e){a.panelOpen&&a.activePanel===e?pe():S(e)}function w(){a.activePanel==="settings"?g.innerHTML=He():a.activePanel==="chat"&&(g.innerHTML=$e(),D())}function He(){let e=Object.entries($).map(([y,ge])=>`<option value="${y}" ${a.provider===y?"selected":""}>${ge.name}</option>`).join(""),o=$[a.provider],t=o?o.models.map(y=>`<option value="${y.id}" ${a.model===y.id?"selected":""}>${y.name}</option>`).join(""):'<option value="">Select provider first</option>',n=o?.local||!1,s=o?.keyUrl||"",i=o?.keyPlaceholder||"Enter API key...",r=a.updateAvailable?`<div class="om-update-banner">v${a.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",l=a.hasApiKey?`<div class="om-status om-status-success">${d.check} Connected</div>`:"",c=a.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':a.saveStatus==="saved"?`${d.check} Saved`:"Save",b=a.saveStatus==="saving"?"om-btn om-btn-saving":a.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",ue=a.saveStatus==="saving"?"disabled":"";return`
314
- ${r}
325
+ </div>`}function Oe(e){e.addEventListener("click",t=>{let o=t.target.closest("[data-action]");if(!o)return;t.preventDefault(),t.stopPropagation();let a=o.dataset.action;Ae(a,o)}),e.addEventListener("change",t=>{let o=t.target,a=o.dataset.field;a&&(a==="provider"?(n.provider=o.value,n.model=_[n.provider]?.models[0]?.id||"",n.saveStatus="",k()):a==="model"&&(n.model=o.value))}),L.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),ke())}),oe(t=>{t.type==="reconnected"&&(n.connected=!0,X())})}function be(e){return n.roots.length>0?n.roots[0]+"/"+e:e}async function Re(e){let t=e.dataset.file,o=e.dataset.search,a=e.dataset.replace;if(!t||!o||!a)return;let r=V(o),s=V(a),i=e.closest(".om-diff-card");try{let c=(await S("fs.read",{path:be(t)})).payload?.content,g=c?c.split(r).length-1:0;if(g===0)n.messages.push({role:"system",content:`Could not find matching code in ${t}`});else if(g>1)n.messages.push({role:"system",content:`Found ${g} matches in ${t} \u2014 expected exactly 1. Edit not applied.`});else{let x=await S("fs.write",{path:be(t),content:c.replace(r,s)});if(x?.payload?.ok===!1)n.messages.push({role:"system",content:`Write failed: ${t} - ${x.payload.error||"unknown"}`});else{let m=i?.dataset.diffIdx;m!==void 0&&(n.messages[parseInt(m)]={role:"system",content:`Applied change to ${t}`})}}}catch(l){n.messages.push({role:"system",content:`Failed: ${t} - ${l.message}`})}k(),P()}function De(e){let t=e.dataset.idx;if(t!==void 0){let o=parseInt(t),r=n.messages[o]?.content.split("__")?.[3]||"file";n.messages[o]={role:"system",content:`Rejected change to ${r}`}}k(),P()}function Ae(e,t){switch(e){case"select":ze();break;case"screenshot":Ue();break;case"chat":ye("chat");break;case"settings":ye("settings");break;case"close-panel":we();break;case"prompt-send":ke();break;case"save-settings":Ie();break;case"get-key":{let o=t.dataset.url;o&&window.open(o,"_blank","noopener");break}case"apply-diff":Re(t);break;case"reject-diff":De(t);break;case"clear-element":n.selectedElement=null,B();break;case"clear-screenshot":n.screenshot=null,B();break}}function X(){let e=w.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${n.connected?"connected":"disconnected"}`)}function N(){w.querySelectorAll(".om-pill-btn").forEach(e=>{let t=e.dataset.action;e.classList.toggle("active",t===n.activePanel||t==="select"&&n.selecting)})}function B(){let e=[];n.selectedElement&&e.push(`<span class="om-prompt-chip">${n.selectedElement.tagName}${n.selectedElement.id?"#"+n.selectedElement.id:""} <button class="om-prompt-chip-x" data-action="clear-element">${p.x}</button></span>`),n.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${p.x}</button></span>`),ve.innerHTML=e.join("")}function T(e){n.panelOpen=!0,n.activePanel=e,J.classList.remove("om-hidden");let t=w.querySelector(".om-panel-title");t&&(t.textContent=e==="settings"?"Settings":"Chat"),k(),N()}function we(){n.panelOpen=!1,n.activePanel="",J.classList.add("om-hidden"),N()}function ye(e){n.panelOpen&&n.activePanel===e?we():T(e)}function k(){n.activePanel==="settings"?y.innerHTML=qe():n.activePanel==="chat"&&(y.innerHTML=Be(),P())}function qe(){let e=Object.entries(_).map(([m,d])=>`<option value="${m}" ${n.provider===m?"selected":""}>${d.name}</option>`).join(""),t=_[n.provider],o=t?t.models.map(m=>`<option value="${m.id}" ${n.model===m.id?"selected":""}>${m.name}</option>`).join(""):'<option value="">Select provider first</option>',a=t?.local||!1,r=t?.keyUrl||"",s=t?.keyPlaceholder||"Enter API key...",i=n.updateAvailable?`<div class="om-update-banner">v${n.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",l=n.hasApiKey?`<div class="om-status om-status-success">${p.check} Connected</div>`:"",c=n.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':n.saveStatus==="saved"?`${p.check} Saved`:"Save",g=n.saveStatus==="saving"?"om-btn om-btn-saving":n.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",x=n.saveStatus==="saving"?"disabled":"";return`
326
+ ${i}
315
327
  <div class="om-settings">
316
328
  <div class="om-field">
317
329
  <label class="om-label">Provider</label>
@@ -319,17 +331,25 @@
319
331
  </div>
320
332
  <div class="om-field">
321
333
  <label class="om-label">Model</label>
322
- <select class="om-select" data-field="model"><option value="">Select Model...</option>${t}</select>
334
+ <select class="om-select" data-field="model"><option value="">Select Model...</option>${o}</select>
323
335
  </div>
324
- <div class="om-field ${n?"om-hidden":""}">
336
+ <div class="om-field ${a?"om-hidden":""}">
325
337
  <label class="om-label">API Key</label>
326
338
  <div class="om-key-row">
327
- <input type="text" class="om-input om-key-input" data-field="apiKey" placeholder="${i}" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
328
- ${s?`<button class="om-btn-get-key" data-action="get-key" data-url="${s}">${d.externalLink} Get key</button>`:""}
339
+ <input type="text" class="om-input om-key-input" data-field="apiKey" placeholder="${s}" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
340
+ ${r?`<button class="om-btn-get-key" data-action="get-key" data-url="${r}">${p.externalLink} Get key</button>`:""}
329
341
  </div>
330
- ${s?`<div class="om-key-hint"><a data-action="get-key" data-url="${s}">Get your ${o?.name||""} API key here</a></div>`:""}
342
+ ${r?`<div class="om-key-hint"><a data-action="get-key" data-url="${r}">Get your ${t?.name||""} API key here</a></div>`:""}
331
343
  </div>
332
- <button class="${b}" data-action="save-settings" ${ue}>${c}</button>
344
+ <button class="${g}" data-action="save-settings" ${x}>${c}</button>
333
345
  ${l}
334
- </div>`}function $e(){if(!a.provider||!a.hasApiKey&&!$[a.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=a.messages.map(n=>`<div class="om-msg om-msg-${n.role}">${U(n.content)}</div>`).join(""),o=a.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${U(a.streamContent)}</div>`:"";return`<div class="om-chat-messages">${!a.messages.length&&!a.streaming?'<div class="om-chat-empty">Select an element or type below to start</div>':""}${e}${o}</div>`}function D(){requestAnimationFrame(()=>{let e=g.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function Pe(){let o=g.querySelector('[data-field="apiKey"]')?.value||"";if(!a.provider){a.saveStatus="error",H(),setTimeout(()=>{a.saveStatus="",w()},2e3);return}if(!V()){a.saveStatus="error",H();let n=g.querySelector('[data-action="save-settings"]');n&&(n.innerHTML="Not connected - check terminal"),setTimeout(()=>{a.saveStatus="",w()},3e3);return}let t={provider:a.provider,model:a.model};o&&(t.apiKey=o),a.saveStatus="saving",H();try{let n=await Promise.race([v("config.set",t),new Promise((s,i)=>setTimeout(()=>i(new Error("Save timed out")),8e3))]);a.hasApiKey=!!(o||a.hasApiKey),a.saveStatus="saved",H(),setTimeout(()=>{a.saveStatus="",a.activePanel==="settings"&&S("chat")},1200)}catch(n){a.saveStatus="error";let s=g.querySelector('[data-action="save-settings"]'),i=(n?.message||"").includes("timeout")?"Connection timeout - is the CLI running?":(n?.message||"").includes("connected")?"Not connected to OpenMagic server":`Save failed: ${n?.message||"Unknown error"}`;s&&(s.innerHTML=i,s.className="om-btn",s.disabled=!1),setTimeout(()=>{a.saveStatus="",w()},4e3)}}function H(){let e=g.querySelector('[data-action="save-settings"]');e&&(a.saveStatus==="saving"?(e.innerHTML='<span class="om-spinner"></span> Saving...',e.className="om-btn om-btn-saving",e.disabled=!0):a.saveStatus==="saved"?(e.innerHTML=`${d.check} Saved`,e.className="om-btn om-btn-saved",e.disabled=!1):a.saveStatus==="error"?(e.innerHTML="Save failed - try again",e.className="om-btn",e.disabled=!1):(e.innerHTML="Save",e.className="om-btn",e.disabled=!1))}async function me(){let e=k.value.trim();if(!e||a.streaming)return;if(!a.provider||!a.hasApiKey&&!$[a.provider]?.local){S("settings");return}a.messages.push({role:"user",content:e}),a.streaming=!0,a.streamContent="",k.value="",S("chat");let o=ae(a.selectedElement,a.screenshot);o.pageUrl=window.location.href,o.pageTitle=document.title;try{let t=await v("fs.list",{});t?.payload?.projectTree&&(o.projectTree=t.payload.projectTree)}catch{}try{let t=await j("llm.chat",{provider:a.provider,model:a.model,messages:a.messages.map(n=>({role:n.role,content:n.content})),context:o},n=>{a.streamContent+=n;let s=g.querySelector(".om-msg-assistant:last-child");s&&(s.innerHTML=`<span class="om-spinner"></span>${U(a.streamContent)}`,D())});if(a.messages.push({role:"assistant",content:a.streamContent||t?.content||""}),t?.modifications?.length){for(let n of t.modifications)if(n.type==="edit"&&n.file&&n.search&&n.replace)try{let i=(await v("fs.read",{path:le(n.file)})).payload?.content;if(i?.includes(n.search)){let r=await v("fs.write",{path:le(n.file),content:i.replace(n.search,n.replace)});r?.payload?.ok===!1?a.messages.push({role:"system",content:`Write failed: ${n.file} - ${r.payload.error||"unknown"}`}):a.messages.push({role:"system",content:`Applied change to ${n.file}`})}}catch(s){a.messages.push({role:"system",content:`Failed: ${n.file} - ${s.message}`})}}}catch(t){a.messages.push({role:"system",content:`Error: ${t.message}`})}a.streaming=!1,a.streamContent="",w(),D()}function le(e){return a.roots.length>0?a.roots[0]+"/"+e:e}var L=null,E=null;function Ne(){a.selecting?B():N()}function N(){a.selecting=!0,document.body.style.cursor="crosshair",M(),E=o=>{let t=o.target;if(t.closest("openmagic-toolbar")||t.dataset?.openmagic)return;let n=t.getBoundingClientRect();W({x:n.x,y:n.y,width:n.width,height:n.height})},L=o=>{o.preventDefault(),o.stopPropagation();let t=o.target;t.closest("openmagic-toolbar")||t.dataset?.openmagic||(a.selectedElement=F(t),B(),P(),k.focus())};let e=o=>{o.key==="Escape"&&B()};document.addEventListener("mousemove",E,!0),document.addEventListener("click",L,!0),document.addEventListener("keydown",e,!0),N._escHandler=e}function B(){a.selecting=!1,document.body.style.cursor="",X(),E&&(document.removeEventListener("mousemove",E,!0),E=null),L&&(document.removeEventListener("click",L,!0),L=null);let e=N._escHandler;e&&(document.removeEventListener("keydown",e,!0),N._escHandler=null),M()}async function _e(){let e=await Y();e&&(a.screenshot=e,P(),k.focus())}function Oe(){let e=!1,o=0,t=0,n=0,s=0;f.addEventListener("mousedown",i=>{let r=i.target;if(r.closest("[data-action]")||!r.closest(".om-grab")&&!r.closest(".om-pill-brand"))return;e=!0,o=i.clientX,t=i.clientY;let l=f.getBoundingClientRect();n=l.left,s=l.top,i.preventDefault()}),document.addEventListener("mousemove",i=>{e&&(f.style.left=n+i.clientX-o+"px",f.style.top=s+i.clientY-t+"px",f.style.right="auto",f.style.bottom="auto")}),document.addEventListener("mouseup",()=>{e=!1})}function U(e){let o=document.createElement("div");return o.textContent=e,o.innerHTML}function Re(){fetch("https://registry.npmjs.org/openmagic/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(5e3)}).then(e=>e.ok?e.json():null).then(e=>{if(!e?.version)return;let o=e.version.split(".").map(Number),t=ce.split(".").map(Number);for(let n=0;n<3;n++){if((o[n]||0)>(t[n]||0)){a.updateAvailable=!0,a.latestVersion=e.version,Ae();return}if((o[n]||0)<(t[n]||0))return}}).catch(()=>{})}function Ae(){if(h.querySelector(".om-update-dot"))return;let o=document.createElement("span");o.className="om-update-dot",o.title=`v${a.latestVersion} available`,o.addEventListener("click",()=>S("settings"));let t=h.querySelector(".om-toolbar-header");t&&t.appendChild(o)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",se):se());})();
346
+ </div>`}function Be(){if(!n.provider||!n.hasApiKey&&!_[n.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=n.messages.map((a,r)=>{if(a.content.startsWith("__DIFF__"))try{let s=JSON.parse(V(a.content.slice(8))),i=F(s.search),l=F(s.replace);return`<div class="om-diff-card" data-diff-idx="${r}">
347
+ <div class="om-diff-file">${E(s.file)}</div>
348
+ <div class="om-diff-removed">${E(s.search.slice(0,200))}</div>
349
+ <div class="om-diff-added">${E(s.replace.slice(0,200))}</div>
350
+ <div class="om-diff-actions">
351
+ <button class="om-btn om-btn-sm" data-action="apply-diff" data-file="${E(s.file)}" data-search="${i}" data-replace="${l}">Apply</button>
352
+ <button class="om-btn-secondary om-btn-sm" data-action="reject-diff" data-idx="${r}">Reject</button>
353
+ </div>
354
+ </div>`}catch{return'<div class="om-msg om-msg-system">Malformed diff data</div>'}return`<div class="om-msg om-msg-${a.role}">${E(a.content)}</div>`}).join(""),t=n.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${E(n.streamContent)}</div>`:"";return`<div class="om-chat-messages">${!n.messages.length&&!n.streaming?'<div class="om-chat-empty">Select an element or type below to start</div>':""}${e}${t}</div>`}function P(){requestAnimationFrame(()=>{let e=y.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function Ie(){let t=y.querySelector('[data-field="apiKey"]')?.value||"";if(!n.provider){n.saveStatus="error",q(),setTimeout(()=>{n.saveStatus="",k()},2e3);return}if(!ne()){n.saveStatus="error",q();let a=y.querySelector('[data-action="save-settings"]');a&&(a.innerHTML="Not connected - check terminal"),setTimeout(()=>{n.saveStatus="",k()},3e3);return}let o={provider:n.provider,model:n.model};t&&(o.apiKey=t),n.saveStatus="saving",q();try{let a=await Promise.race([S("config.set",o),new Promise((r,s)=>setTimeout(()=>s(new Error("Save timed out")),8e3))]);n.hasApiKey=!!(t||n.hasApiKey),n.saveStatus="saved",q(),setTimeout(()=>{n.saveStatus="",n.activePanel==="settings"&&T("chat")},1200)}catch(a){n.saveStatus="error";let r=y.querySelector('[data-action="save-settings"]'),s=(a?.message||"").includes("timeout")?"Connection timeout - is the CLI running?":(a?.message||"").includes("connected")?"Not connected to OpenMagic server":`Save failed: ${a?.message||"Unknown error"}`;r&&(r.innerHTML=s,r.className="om-btn",r.disabled=!1),setTimeout(()=>{n.saveStatus="",k()},4e3)}}function q(){let e=y.querySelector('[data-action="save-settings"]');e&&(n.saveStatus==="saving"?(e.innerHTML='<span class="om-spinner"></span> Saving...',e.className="om-btn om-btn-saving",e.disabled=!0):n.saveStatus==="saved"?(e.innerHTML=`${p.check} Saved`,e.className="om-btn om-btn-saved",e.disabled=!1):n.saveStatus==="error"?(e.innerHTML="Save failed - try again",e.className="om-btn",e.disabled=!1):(e.innerHTML="Save",e.className="om-btn",e.disabled=!1))}async function ke(){let e=L.value.trim();if(!e||n.streaming)return;if(!n.provider||!n.hasApiKey&&!_[n.provider]?.local){T("settings");return}n.messages.push({role:"user",content:e}),n.streaming=!0,n.streamContent="",L.value="",T("chat");let t=he(n.selectedElement,n.screenshot);t.pageUrl=window.location.href,t.pageTitle=document.title;let o=4,a=24e3,r=/\.(?:[cm]?[jt]sx?|svelte|vue|astro|html?|css|scss|less|php|py)$/i;try{let s=await S("fs.list",{});s?.payload?.projectTree&&(t.projectTree=s.payload.projectTree);let l=(s?.payload?.files||[]).filter(d=>d.type==="file"&&r.test(d.path)),c=[e,n.selectedElement?.tagName,n.selectedElement?.id,n.selectedElement?.className,n.selectedElement?.textContent].filter(Boolean).join(" ").toLowerCase().split(/[^a-z0-9_-]+/).filter(d=>d.length>=2),g=l.map(d=>{let v=0,O=d.path.toLowerCase();for(let R of c)O.includes(R)&&(v+=5);return/(component|page|route|app|src|view|template)/.test(O)&&(v+=2),{...d,score:v}}).sort((d,v)=>v.score-d.score),x=[],m=0;for(let d of g.slice(0,o)){if(m>=a)break;try{let v=n.roots[0]||"",O=await S("fs.read",{path:v?`${v}/${d.path}`:d.path}),R=String(O?.payload?.content||"");if(!R)continue;let Y=R.slice(0,Math.min(8e3,a-m));x.push({path:d.path,content:Y}),m+=Y.length}catch{}}x.length&&(t.files=x)}catch{}try{let s=await te("llm.chat",{provider:n.provider,model:n.model,messages:n.messages.map(i=>({role:i.role,content:i.content})),context:t},i=>{n.streamContent+=i;let l=y.querySelector(".om-msg-assistant:last-child");l&&(l.innerHTML=`<span class="om-spinner"></span>${E(n.streamContent)}`,P())});if(n.messages.push({role:"assistant",content:n.streamContent||s?.content||""}),s?.modifications?.length){for(let i of s.modifications)if(i.type==="edit"&&i.file&&i.search&&i.replace){let l=Math.random().toString(36).slice(2),c=JSON.stringify({id:l,file:i.file,search:i.search,replace:i.replace});n.messages.push({role:"system",content:`__DIFF__${F(c)}`})}}}catch(s){n.messages.push({role:"system",content:`Error: ${s.message}`})}n.streaming=!1,n.streamContent="",k(),P()}var $=null,H=null;function ze(){n.selecting?W():I()}function I(){n.selecting=!0,document.body.style.cursor="crosshair",N(),H=t=>{let o=t.target;if(o.closest("openmagic-toolbar")||o.dataset?.openmagic)return;let a=o.getBoundingClientRect();se({x:a.x,y:a.y,width:a.width,height:a.height})},$=t=>{t.preventDefault(),t.stopPropagation();let o=t.target;o.closest("openmagic-toolbar")||o.dataset?.openmagic||(n.selectedElement=ae(o),W(),B(),L.focus())};let e=t=>{t.key==="Escape"&&W()};document.addEventListener("mousemove",H,!0),document.addEventListener("click",$,!0),document.addEventListener("keydown",e,!0),I._escHandler=e}function W(){n.selecting=!1,document.body.style.cursor="",re(),H&&(document.removeEventListener("mousemove",H,!0),H=null),$&&(document.removeEventListener("click",$,!0),$=null);let e=I._escHandler;e&&(document.removeEventListener("keydown",e,!0),I._escHandler=null),N()}async function Ue(){let e;try{let o=n.selectedElement?.cssSelector?.trim();o&&(e=document.querySelector(o)||void 0)}catch{}let t=await ie(e||void 0);t&&(n.screenshot=t,B(),L.focus())}function je(){let e=!1,t=0,o=0,a=0,r=0;u.addEventListener("mousedown",s=>{let i=s.target;if(i.closest("[data-action]")||!i.closest(".om-grab")&&!i.closest(".om-pill-brand"))return;e=!0,t=s.clientX,o=s.clientY;let l=u.getBoundingClientRect();a=l.left,r=l.top,s.preventDefault()}),document.addEventListener("mousemove",s=>{e&&(u.style.left=a+s.clientX-t+"px",u.style.top=r+s.clientY-o+"px",u.style.right="auto",u.style.bottom="auto")}),document.addEventListener("mouseup",()=>{if(e){e=!1;try{localStorage.setItem("__om_pos__",JSON.stringify({left:u.style.left,top:u.style.top}))}catch{}}})}function E(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function Ge(){fetch("https://registry.npmjs.org/openmagic/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(5e3)}).then(e=>e.ok?e.json():null).then(e=>{if(!e?.version)return;let t=e.version.split(".").map(Number),o=xe.split(".").map(Number);for(let a=0;a<3;a++){if((t[a]||0)>(o[a]||0)){n.updateAvailable=!0,n.latestVersion=e.version,Ke();return}if((t[a]||0)<(o[a]||0))return}}).catch(()=>{})}function Ke(){if(w.querySelector(".om-update-dot"))return;let t=document.createElement("span");t.className="om-update-dot",t.title=`v${n.latestVersion} available`,t.addEventListener("click",()=>T("settings"));let o=w.querySelector(".om-toolbar-header");o&&o.appendChild(t)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",fe):fe());})();
335
355
  //# sourceMappingURL=index.global.js.map