openmagic 0.16.0 → 0.17.1

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 Z=`
2
+ "use strict";var OpenMagicToolbar=(()=>{var ae=`
3
3
  :host {
4
4
  all: initial;
5
5
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
@@ -167,6 +167,36 @@
167
167
  .om-prompt-send:hover { background: #7c6cf7; }
168
168
  .om-prompt-send:disabled { background: #2a2a4a; color: #444; cursor: not-allowed; }
169
169
 
170
+ .om-prompt-attach {
171
+ display: flex; align-items: center; justify-content: center;
172
+ width: 28px; height: 28px; flex-shrink: 0;
173
+ background: none; border: none; color: #555;
174
+ cursor: pointer; border-radius: 6px; transition: color 0.15s, background 0.15s;
175
+ }
176
+ .om-prompt-attach:hover { color: #a29bfe; background: rgba(108, 92, 231, 0.1); }
177
+
178
+ /* \u2500\u2500 Attachments \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 */
179
+ .om-prompt-attachments {
180
+ display: flex; gap: 6px; padding: 4px 8px; flex-wrap: wrap;
181
+ border-bottom: 1px solid rgba(255,255,255,0.03);
182
+ }
183
+ .om-attachment-thumb {
184
+ position: relative; width: 48px; height: 48px;
185
+ border-radius: 6px; overflow: hidden;
186
+ border: 1px solid rgba(255,255,255,0.08);
187
+ }
188
+ .om-attachment-thumb img {
189
+ width: 100%; height: 100%; object-fit: cover;
190
+ }
191
+ .om-attachment-remove {
192
+ position: absolute; top: 1px; right: 1px;
193
+ width: 16px; height: 16px; display: flex;
194
+ align-items: center; justify-content: center;
195
+ background: rgba(0,0,0,0.7); border: none; border-radius: 50%;
196
+ color: #fff; cursor: pointer; padding: 0; line-height: 1;
197
+ }
198
+ .om-attachment-remove svg { width: 10px; height: 10px; }
199
+
170
200
  /* \u2500\u2500 Settings \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\u2500\u2500\u2500 */
171
201
  .om-settings { display: flex; flex-direction: column; gap: 12px; }
172
202
 
@@ -291,74 +321,78 @@
291
321
  .om-btn-secondary:hover { background: rgba(255,255,255,0.08); color: #ccc; }
292
322
  .om-diff-applied { opacity: 0.5; }
293
323
  .om-diff-applied .om-diff-actions { display: none; }
294
- `;var b=null,h=new Map,P=[],G=[],T=!1,ee=!1,U=null,j=0;function K(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function F(e,o){return ee=!0,new Promise((n,a)=>{let r=!1,s=setTimeout(()=>{r||(r=!0,a(new Error("Handshake timeout")),b?.close())},1e4);try{let i=window.location.hostname||"127.0.0.1",l=window.location.protocol==="https:"?"wss:":"ws:";b=new WebSocket(`${l}//${i}:${e}/__openmagic__/ws`),b.onopen=()=>{let d=K();b.send(JSON.stringify({id:d,type:"handshake",payload:{token:o}})),h.set(d,c=>{if(c.type==="handshake.ok"){clearTimeout(s),T=!0,j=0;for(let m of G)b?.send(m);G=[],r||(r=!0,n())}else c.type==="error"&&(clearTimeout(s),r||(r=!0,a(new Error(c.payload?.message||"Handshake failed"))))})},b.onmessage=d=>{try{let c=JSON.parse(d.data);c.id&&h.has(c.id)&&(h.get(c.id)(c),(c.type==="llm.done"||c.type==="llm.error"||!c.type.startsWith("llm."))&&h.delete(c.id));for(let m of P)m(c)}catch{}},b.onclose=()=>{let d=T;if(T=!1,h.forEach((c,m)=>{c({type:"error",id:m,payload:{message:"Connection lost"}})}),h.clear(),!d&&!r){clearTimeout(s),r=!0,a(new Error("WebSocket closed before handshake"));return}if(d&&ee&&!U){let c=Math.min(2e3*Math.pow(1.5,j),3e4);j++,U=setTimeout(()=>{U=null,F(e,o).then(()=>{for(let m of P)m({type:"reconnected",payload:{}})}).catch(()=>{})},c)}},b.onerror=()=>{!T&&!r&&(clearTimeout(s),r=!0,a(new Error("WebSocket connection failed")))}}catch(i){clearTimeout(s),r||(r=!0,a(i))}})}function te(e){let o=JSON.stringify(e);b&&b.readyState===WebSocket.OPEN&&T?b.send(o):G.push(o)}function E(e,o){return new Promise((n,a)=>{let r=K(),s=setTimeout(()=>{h.delete(r),a(new Error("Request timeout"))},3e4);h.set(r,i=>{clearTimeout(s),i.type==="error"?a(new Error(i.payload?.message||"Unknown error")):n(i)}),te({id:r,type:e,payload:o})})}function oe(e,o,n){return new Promise((a,r)=>{let s=K(),i=setTimeout(()=>{h.delete(s),r(new Error("Stream timeout"))},12e4);h.set(s,l=>{l.type==="llm.chunk"?n(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(i),h.delete(s),a(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(i),h.delete(s),r(new Error(l.payload?.message||"Stream error")))}),te({id:s,type:e,payload:o})})}function ne(e){return P.push(e),()=>{P=P.filter(o=>o!==e)}}function ae(){return T}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 se(e){let o=window.getComputedStyle(e),n={};for(let r of Ee)n[r]=o.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:n,rect:{x:a.x,y:a.y,width:a.width,height:a.height}}}function Me(e){let o=e.cloneNode(!0);o.querySelectorAll("script, style, svg").forEach(r=>r.remove());let a=o.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(`
295
- `);a=`<${r} ${s}>
324
+ `;var b=null,f=new Map,_=[],F=[],$=!1,se=!1,j=null,U=0;function G(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function K(e,o){return se=!0,new Promise((n,a)=>{let s=!1,r=setTimeout(()=>{s||(s=!0,a(new Error("Handshake timeout")),b?.close())},1e4);try{let i=window.location.hostname||"127.0.0.1",l=window.location.protocol==="https:"?"wss:":"ws:";b=new WebSocket(`${l}//${i}:${e}/__openmagic__/ws`),b.onopen=()=>{let c=G();b.send(JSON.stringify({id:c,type:"handshake",payload:{token:o}})),f.set(c,d=>{if(d.type==="handshake.ok"){clearTimeout(r),$=!0,U=0;for(let p of F)b?.send(p);F=[],s||(s=!0,n())}else d.type==="error"&&(clearTimeout(r),s||(s=!0,a(new Error(d.payload?.message||"Handshake failed"))))})},b.onmessage=c=>{try{let d=JSON.parse(c.data);d.id&&f.has(d.id)&&(f.get(d.id)(d),(d.type==="llm.done"||d.type==="llm.error"||!d.type.startsWith("llm."))&&f.delete(d.id));for(let p of _)p(d)}catch{}},b.onclose=()=>{let c=$;if($=!1,f.forEach((d,p)=>{d({type:"error",id:p,payload:{message:"Connection lost"}})}),f.clear(),!c&&!s){clearTimeout(r),s=!0,a(new Error("WebSocket closed before handshake"));return}if(c&&se&&!j){let d=Math.min(2e3*Math.pow(1.5,U),3e4);U++,j=setTimeout(()=>{j=null,K(e,o).then(()=>{for(let p of _)p({type:"reconnected",payload:{}})}).catch(()=>{})},d)}},b.onerror=()=>{!$&&!s&&(clearTimeout(r),s=!0,a(new Error("WebSocket connection failed")))}}catch(i){clearTimeout(r),s||(s=!0,a(i))}})}function re(e){let o=JSON.stringify(e);b&&b.readyState===WebSocket.OPEN&&$?b.send(o):F.push(o)}function E(e,o){return new Promise((n,a)=>{let s=G(),r=setTimeout(()=>{f.delete(s),a(new Error("Request timeout"))},3e4);f.set(s,i=>{clearTimeout(r),i.type==="error"?a(new Error(i.payload?.message||"Unknown error")):n(i)}),re({id:s,type:e,payload:o})})}function ie(e,o,n){return new Promise((a,s)=>{let r=G(),i=setTimeout(()=>{f.delete(r),s(new Error("Stream timeout"))},12e4);f.set(r,l=>{l.type==="llm.chunk"?n(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(i),f.delete(r),a(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(i),f.delete(r),s(new Error(l.payload?.message||"Stream error")))}),re({id:r,type:e,payload:o})})}function le(e){return _.push(e),()=>{_=_.filter(o=>o!==e)}}function ce(){return $}var $e=["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 de(e){let o=window.getComputedStyle(e),n={};for(let s of $e)n[s]=o.getPropertyValue(s);let a=e.getBoundingClientRect();return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().slice(0,200),outerHTML:Ce(e),cssSelector:He(e),xpath:Pe(e),computedStyles:n,rect:{x:a.x,y:a.y,width:a.width,height:a.height}}}function Ce(e){let o=e.cloneNode(!0);o.querySelectorAll("script, style, svg").forEach(s=>s.remove());let a=o.outerHTML;if(a.length>2e3){let s=e.tagName.toLowerCase(),r=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(`
325
+ `);a=`<${s} ${r}>
296
326
  ${i}
297
327
  ${e.children.length>5?`<!-- +${e.children.length-5} more children -->`:""}
298
- </${r}>`}return a}function Le(e){if(e.id)return`#${CSS.escape(e.id)}`;let o=[],n=e;for(;n&&n!==document.body;){let a=n.tagName.toLowerCase();if(n.id){o.unshift(`#${CSS.escape(n.id)}`);break}if(n.className&&typeof n.className=="string"){let s=n.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=n.parentElement;if(r){let s=Array.from(r.children).filter(i=>i.tagName===n.tagName);if(s.length>1){let i=s.indexOf(n)+1;a+=`:nth-of-type(${i})`}}o.unshift(a),n=n.parentElement}return o.join(" > ")}function Te(e){let o=[],n=e;for(;n&&n!==document;){if(n.nodeType===Node.ELEMENT_NODE){let a=n,r=1,s=a.previousElementSibling;for(;s;)s.tagName===a.tagName&&r++,s=s.previousElementSibling;o.unshift(`${a.tagName.toLowerCase()}[${r}]`)}n=n.parentNode}return"/"+o.join("/")}var y=null;function re(e){y||(y=document.createElement("div"),y.style.cssText=`
328
+ </${s}>`}return a}function He(e){if(e.id)return`#${CSS.escape(e.id)}`;let o=[],n=e;for(;n&&n!==document.body;){let a=n.tagName.toLowerCase();if(n.id){o.unshift(`#${CSS.escape(n.id)}`);break}if(n.className&&typeof n.className=="string"){let r=n.className.trim().split(/\s+/).filter(i=>!i.startsWith("__")&&i.length<30).slice(0,2).map(i=>CSS.escape(i));r.length>0&&(a+="."+r.join("."))}let s=n.parentElement;if(s){let r=Array.from(s.children).filter(i=>i.tagName===n.tagName);if(r.length>1){let i=r.indexOf(n)+1;a+=`:nth-of-type(${i})`}}o.unshift(a),n=n.parentElement}return o.join(" > ")}function Pe(e){let o=[],n=e;for(;n&&n!==document;){if(n.nodeType===Node.ELEMENT_NODE){let a=n,s=1,r=a.previousElementSibling;for(;r;)r.tagName===a.tagName&&s++,r=r.previousElementSibling;o.unshift(`${a.tagName.toLowerCase()}[${s}]`)}n=n.parentNode}return"/"+o.join("/")}var y=null;function pe(e){y||(y=document.createElement("div"),y.style.cssText=`
299
329
  position: fixed;
300
330
  pointer-events: none;
301
331
  z-index: 2147483646;
302
332
  border: 2px solid #6c5ce7;
303
333
  background: rgba(108, 92, 231, 0.1);
304
334
  transition: all 0.1s ease;
305
- `,y.dataset.openmagic="highlight",document.body.appendChild(y)),y.style.left=`${e.x}px`,y.style.top=`${e.y}px`,y.style.width=`${e.width}px`,y.style.height=`${e.height}px`,y.style.display="block"}function ie(){y&&(y.style.display="none")}async function le(e){try{return e?await $e(e):await Ce()}catch(o){return console.warn("[OpenMagic] Screenshot capture failed:",o),null}}async function Ce(){let e=document.createElement("canvas"),o=window.devicePixelRatio||1;e.width=window.innerWidth*o,e.height=window.innerHeight*o;let n=e.getContext("2d");n.scale(o,o);try{let a=await ce(document.body),r=await pe(a,window.innerWidth,window.innerHeight);return n.drawImage(r,0,0),e.toDataURL("image/png")}catch{return null}}async function $e(e){let o=e.getBoundingClientRect(),n=document.createElement("canvas"),a=window.devicePixelRatio||1;n.width=o.width*a,n.height=o.height*a;let r=n.getContext("2d");r.scale(a,a);try{let s=await ce(e),i=await pe(s,o.width,o.height);return r.drawImage(i,0,0),n.toDataURL("image/png")}catch{return null}}function ce(e){return new Promise(o=>{let n=e.cloneNode(!0);de(e,n);let a=e.getBoundingClientRect(),r=a.width,s=a.height,i=`
306
- <svg xmlns="http://www.w3.org/2000/svg" width="${r}" height="${s}">
335
+ `,y.dataset.openmagic="highlight",document.body.appendChild(y)),y.style.left=`${e.x}px`,y.style.top=`${e.y}px`,y.style.width=`${e.width}px`,y.style.height=`${e.height}px`,y.style.display="block"}function me(){y&&(y.style.display="none")}async function ue(e){try{return e?await Ne(e):await _e()}catch(o){return console.warn("[OpenMagic] Screenshot capture failed:",o),null}}async function _e(){let e=document.createElement("canvas"),o=window.devicePixelRatio||1;e.width=window.innerWidth*o,e.height=window.innerHeight*o;let n=e.getContext("2d");n.scale(o,o);try{let a=await ge(document.body),s=await fe(a,window.innerWidth,window.innerHeight);return n.drawImage(s,0,0),e.toDataURL("image/png")}catch{return null}}async function Ne(e){let o=e.getBoundingClientRect(),n=document.createElement("canvas"),a=window.devicePixelRatio||1;n.width=o.width*a,n.height=o.height*a;let s=n.getContext("2d");s.scale(a,a);try{let r=await ge(e),i=await fe(r,o.width,o.height);return s.drawImage(i,0,0),n.toDataURL("image/png")}catch{return null}}function ge(e){return new Promise(o=>{let n=e.cloneNode(!0);he(e,n);let a=e.getBoundingClientRect(),s=a.width,r=a.height,i=`
336
+ <svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${r}">
307
337
  <foreignObject width="100%" height="100%">
308
- <div xmlns="http://www.w3.org/1999/xhtml" style="width:${r}px;height:${s}px;overflow:hidden;">
338
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width:${s}px;height:${r}px;overflow:hidden;">
309
339
  ${n.outerHTML}
310
340
  </div>
311
341
  </foreignObject>
312
- </svg>`;o(i)})}function de(e,o){let n=window.getComputedStyle(e),a="";for(let i=0;i<n.length;i++){let l=n[i];a+=`${l}:${n.getPropertyValue(l)};`}o.style.cssText=a;let r=e.children,s=o.children;for(let i=0;i<r.length&&i<s.length;i++)de(r[i],s[i])}function pe(e,o,n){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=o,s.height=n,s.src=l})}var D=[];var me=!1;function ge(){if(me)return;me=!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,V(s),i}catch(i){throw s.status=0,s.duration=Date.now()-s.timestamp,V(s),i}};let o=XMLHttpRequest.prototype.open,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(a,r,...s){return this.__om_method=a,this.__om_url=r,this.__om_start=Date.now(),o.apply(this,[a,r,...s])},XMLHttpRequest.prototype.send=function(...a){return this.addEventListener("loadend",()=>{V({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()})}),n.apply(this,a)}}function V(e){e.url.includes("__openmagic__")||(D.push(e),D.length>50&&D.shift())}function He(){return[...D]}var q=[],Pe=100,ue=!1;function fe(){if(ue)return;ue=!0;let e=["log","warn","error","info","debug"];for(let o of e){let n=console[o];console[o]=function(...a){q.push({level:o,args:a.map(r=>{try{return typeof r=="object"?JSON.stringify(r).slice(0,500):String(r)}catch{return String(r)}}),timestamp:Date.now()}),q.length>Pe&&q.shift(),n.apply(console,a)}}}function _e(){return[...q]}function he(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:He().map(n=>({method:n.method,url:n.url,status:n.status,duration:n.duration,timestamp:n.timestamp})),consoleLogs:_e().map(n=>({level:n.level,args:n.args,timestamp:n.timestamp}))}}var g={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>'},C={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 X(e){let o=new TextEncoder().encode(e),n="";for(let a=0;a<o.length;a+=32768)n+=String.fromCharCode(...o.subarray(a,a+32768));return btoa(n)}function W(e){let o=atob(e),n=new Uint8Array(o.length);for(let a=0;a<o.length;a++)n[a]=o.charCodeAt(a);return new TextDecoder().decode(n)}var xe="0.16.0",t={connected:!1,panelOpen:!1,activePanel:"",selecting:!1,selectedElement:null,screenshot:null,messages:[],streaming:!1,streamContent:"",provider:"",model:"",hasApiKey:!1,configuredProviders:{},roots:[],updateAvailable:!1,latestVersion:"",saveStatus:""},x,f,$,ve,Q,v;function Ne(){try{sessionStorage.setItem("__om_state__",JSON.stringify({messages:t.messages,provider:t.provider,model:t.model,panelOpen:t.panelOpen,activePanel:t.activePanel}))}catch{}}function Oe(){try{let e=JSON.parse(sessionStorage.getItem("__om_state__")||"{}");e.messages?.length&&(t.messages=e.messages),e.provider&&(t.provider=e.provider),e.model&&(t.model=e.model),e.panelOpen&&(t.panelOpen=e.panelOpen,t.activePanel=e.activePanel||"")}catch{}}function ye(){if(document.querySelector("openmagic-toolbar"))return;Oe();let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",x=e.attachShadow({mode:"closed"});let o=document.createElement("style");o.textContent=Z,x.appendChild(o);let n=document.createElement("div");x.appendChild(n),n.innerHTML=Re(),f=n.querySelector(".om-toolbar"),$=n.querySelector(".om-prompt-input"),ve=n.querySelector(".om-prompt-context"),Q=n.querySelector(".om-panel"),v=n.querySelector(".om-panel-body"),document.body.appendChild(e),Ae(n),Fe();try{let i=JSON.parse(localStorage.getItem("__om_pos__")||"");i?.left&&i?.top&&(f.style.left=i.left,f.style.top=i.top,f.style.right="auto",f.style.bottom="auto")}catch{}ge(),fe(),Ve();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&&F(s,r).then(()=>(t.connected=!0,J(),E("config.get"))).then(i=>{let l=i.payload?.provider||"",d=i.payload?.model||"";t.provider=t.provider||l,t.model=t.model||d,t.configuredProviders=i.payload?.apiKeys||{},t.hasApiKey=t.configuredProviders[t.provider]||!1,t.roots=i.payload?.roots||[],t.panelOpen&&t.activePanel?L(t.activePanel):(!t.provider||!t.hasApiKey&&!Object.values(t.configuredProviders).some(Boolean))&&L("settings"),R()}).catch(()=>{t.connected=!1,J()})}function Re(){return`
342
+ </svg>`;o(i)})}function he(e,o){let n=window.getComputedStyle(e),a="";for(let i=0;i<n.length;i++){let l=n[i];a+=`${l}:${n.getPropertyValue(l)};`}o.style.cssText=a;let s=e.children,r=o.children;for(let i=0;i<s.length&&i<r.length;i++)he(s[i],r[i])}function fe(e,o,n){return new Promise((a,s)=>{let r=new Image,i=new Blob([e],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(i);r.onload=()=>{URL.revokeObjectURL(l),a(r)},r.onerror=()=>{URL.revokeObjectURL(l),s(new Error("Failed to load SVG image"))},r.width=o,r.height=n,r.src=l})}var B=[];var ye=!1;function xe(){if(ye)return;ye=!0;let e=window.fetch;window.fetch=async function(...a){let s=new Request(...a),r={method:s.method,url:s.url,timestamp:Date.now()};try{let i=await e.apply(this,a);return r.status=i.status,r.duration=Date.now()-r.timestamp,V(r),i}catch(i){throw r.status=0,r.duration=Date.now()-r.timestamp,V(r),i}};let o=XMLHttpRequest.prototype.open,n=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(a,s,...r){return this.__om_method=a,this.__om_url=s,this.__om_start=Date.now(),o.apply(this,[a,s,...r])},XMLHttpRequest.prototype.send=function(...a){return this.addEventListener("loadend",()=>{V({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()})}),n.apply(this,a)}}function V(e){e.url.includes("__openmagic__")||(B.push(e),B.length>50&&B.shift())}function W(){return[...B]}var q=[],Oe=100,be=!1;function ve(){if(be)return;be=!0;let e=["log","warn","error","info","debug"];for(let o of e){let n=console[o];console[o]=function(...a){q.push({level:o,args:a.map(s=>{try{return typeof s=="object"?JSON.stringify(s).slice(0,500):String(s)}catch{return String(s)}}),timestamp:Date.now()}),q.length>Oe&&q.shift(),n.apply(console,a)}}}function X(){return[...q]}function we(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:W().map(n=>({method:n.method,url:n.url,status:n.status,duration:n.duration,timestamp:n.timestamp})),consoleLogs:X().map(n=>({level:n.level,args:n.args,timestamp:n.timestamp}))}}var u={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>',network:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>',activity:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>',paperclip:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>',image:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>'},C={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 Q(e){let o=new TextEncoder().encode(e),n="";for(let a=0;a<o.length;a+=32768)n+=String.fromCharCode(...o.subarray(a,a+32768));return btoa(n)}function Z(e){let o=atob(e),n=new Uint8Array(o.length);for(let a=0;a<o.length;a++)n[a]=o.charCodeAt(a);return new TextDecoder().decode(n)}var Se="0.17.1",t={connected:!1,panelOpen:!1,activePanel:"",selecting:!1,selectedElement:null,screenshot:null,messages:[],streaming:!1,streamContent:"",provider:"",model:"",hasApiKey:!1,configuredProviders:{},roots:[],updateAvailable:!1,latestVersion:"",saveStatus:"",networkCapture:!1,attachments:[]},x,h,M,Ee,oe,w;function Re(){try{sessionStorage.setItem("__om_state__",JSON.stringify({messages:t.messages,provider:t.provider,model:t.model,panelOpen:t.panelOpen,activePanel:t.activePanel}))}catch{}}function Ae(){try{let e=JSON.parse(sessionStorage.getItem("__om_state__")||"{}");e.messages?.length&&(t.messages=e.messages),e.provider&&(t.provider=e.provider),e.model&&(t.model=e.model),e.panelOpen&&(t.panelOpen=e.panelOpen,t.activePanel=e.activePanel||"")}catch{}}function ke(){if(document.querySelector("openmagic-toolbar"))return;Ae();let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",x=e.attachShadow({mode:"closed"});let o=document.createElement("style");o.textContent=ae,x.appendChild(o);let n=document.createElement("div");x.appendChild(n),n.innerHTML=De(),h=n.querySelector(".om-toolbar"),M=n.querySelector(".om-prompt-input"),Ee=n.querySelector(".om-prompt-context"),oe=n.querySelector(".om-panel"),w=n.querySelector(".om-panel-body"),document.body.appendChild(e),Be(n),Je();try{let i=JSON.parse(localStorage.getItem("__om_pos__")||"");i?.left&&i?.top&&(h.style.left=i.left,h.style.top=i.top,h.style.right="auto",h.style.bottom="auto")}catch{}xe(),ve(),Ye();let s=document.querySelector("script[data-openmagic-token]")?.dataset.openmagicToken||window.__OPENMAGIC_TOKEN__,r=parseInt(window.location.port,10)||(window.location.protocol==="https:"?443:80);s&&K(r,s).then(()=>(t.connected=!0,ee(),E("config.get"))).then(i=>{let l=i.payload?.provider||"",c=i.payload?.model||"";t.provider=t.provider||l,t.model=t.model||c,t.configuredProviders=i.payload?.apiKeys||{},t.hasApiKey=t.configuredProviders[t.provider]||!1,t.roots=i.payload?.roots||[],t.panelOpen&&t.activePanel?T(t.activePanel):(!t.provider||!t.hasApiKey&&!Object.values(t.configuredProviders).some(Boolean))&&T("settings"),A()}).catch(()=>{t.connected=!1,ee()})}function De(){return`
313
343
  <div class="om-toolbar">
314
344
  <div class="om-toolbar-header">
315
- <span class="om-grab">${g.grip}</span>
345
+ <span class="om-grab">${u.grip}</span>
316
346
  <span class="om-pill-brand">
317
- <span class="om-pill-icon">${g.sparkle}</span>
347
+ <span class="om-pill-icon">${u.sparkle}</span>
318
348
  <span class="om-pill-text">OpenMagic</span>
319
349
  </span>
320
350
  <span class="om-pill-divider"></span>
321
- <button class="om-pill-btn" data-action="select" title="Select element">${g.crosshair}</button>
322
- <button class="om-pill-btn" data-action="screenshot" title="Screenshot">${g.camera}</button>
351
+ <button class="om-pill-btn" data-action="select" title="Select element">${u.crosshair}</button>
352
+ <button class="om-pill-btn" data-action="screenshot" title="Screenshot">${u.camera}</button>
353
+ <button class="om-pill-btn" data-action="network" title="Network & Performance">${u.activity}</button>
323
354
  <span class="om-pill-divider"></span>
324
- <button class="om-pill-btn" data-action="chat" title="Chat">${g.chat}</button>
325
- <button class="om-pill-btn" data-action="settings" title="Settings">${g.settings}</button>
355
+ <button class="om-pill-btn" data-action="chat" title="Chat">${u.chat}</button>
356
+ <button class="om-pill-btn" data-action="settings" title="Settings">${u.settings}</button>
326
357
  <span class="om-status-dot disconnected"></span>
327
358
  </div>
328
359
  <div class="om-panel om-hidden">
329
360
  <div class="om-panel-header">
330
361
  <span class="om-panel-title"></span>
331
- <span class="om-panel-version">v${xe}</span>
332
- <button class="om-panel-close" data-action="close-panel">${g.x}</button>
362
+ <span class="om-panel-version">v${Se}</span>
363
+ <button class="om-panel-close" data-action="close-panel">${u.x}</button>
333
364
  </div>
334
365
  <div class="om-panel-body"></div>
335
366
  </div>
367
+ <div class="om-prompt-attachments"></div>
336
368
  <div class="om-prompt-row">
337
369
  <div class="om-prompt-context"></div>
370
+ <button class="om-prompt-attach" data-action="attach-image" title="Attach image">${u.paperclip}</button>
338
371
  <input class="om-prompt-input" type="text" placeholder="Describe what to change..." autocomplete="off" />
339
- <button class="om-prompt-send" data-action="prompt-send">${g.send}</button>
372
+ <button class="om-prompt-send" data-action="prompt-send">${u.send}</button>
373
+ <input type="file" class="om-file-input om-hidden" accept="image/*" multiple />
340
374
  </div>
341
- </div>`}function Ae(e){e.addEventListener("click",o=>{let n=o.target.closest("[data-action]");if(!n)return;o.preventDefault(),o.stopPropagation();let a=n.dataset.action;Ie(a,n)}),e.addEventListener("change",o=>{let n=o.target,a=n.dataset.field;a&&(a==="provider"?(t.provider=n.value,t.model=C[t.provider]?.models[0]?.id||"",t.hasApiKey=t.configuredProviders[t.provider]||C[t.provider]?.local||!1,t.saveStatus="",w()):a==="model"&&(t.model=n.value))}),$.addEventListener("keydown",o=>{o.key==="Enter"&&!o.shiftKey&&(o.preventDefault(),ke())}),ne(o=>{o.type==="reconnected"&&(t.connected=!0,J())})}function De(e){return t.roots.length>0?t.roots[0]+"/"+e:e}async function qe(e){let o=e.dataset.file,n=e.dataset.search,a=e.dataset.replace;if(!o||!n||!a)return;let r,s;try{r=W(n),s=W(a)}catch{t.messages.push({role:"system",content:`Failed to decode diff data for ${o}`}),w();return}let i=e.closest(".om-diff-card"),l=De(o);if(i){let d=i.querySelector(".om-diff-actions");d&&(d.innerHTML='<span class="om-spinner"></span> Applying...')}try{let c=(await E("fs.read",{path:l}))?.payload?.content;if(!c)t.messages.push({role:"system",content:`Could not read ${o} \u2014 file may not exist at ${l}`});else{let m=c.split(r).length-1;if(m===0)t.messages.push({role:"system",content:`No matching code found in ${o}. The file may have changed since the suggestion was made.`});else if(m>1)t.messages.push({role:"system",content:`Found ${m} matches in ${o} \u2014 expected exactly 1. Edit not applied for safety.`});else{let k=await E("fs.write",{path:l,content:c.replace(r,s)});if(k?.payload?.ok===!1)t.messages.push({role:"system",content:`Write failed: ${o} - ${k.payload?.error||"unknown"}`});else{let p=i?.dataset.diffIdx;p!==void 0?t.messages[parseInt(p)]={role:"system",content:`Applied change to ${o}`}:t.messages.push({role:"system",content:`Applied change to ${o}`})}}}}catch(d){t.messages.push({role:"system",content:`Failed to apply: ${o} \u2014 ${d.message}`})}w(),O()}function Be(e){let o=e.dataset.idx;if(o!==void 0){let n=parseInt(o),r=t.messages[n]?.content.split("__")?.[3]||"file";t.messages[n]={role:"system",content:`Rejected change to ${r}`}}w(),O()}function Ie(e,o){switch(e){case"select":Ge();break;case"screenshot":Ke();break;case"chat":be("chat");break;case"settings":be("settings");break;case"close-panel":we();break;case"prompt-send":ke();break;case"save-settings":je();break;case"get-key":{let n=o.dataset.url;n&&window.open(n,"_blank","noopener");break}case"change-key":{let n=x.querySelector("[data-key-change]");n&&n.classList.remove("om-hidden"),o.style.display="none";break}case"apply-diff":qe(o);break;case"reject-diff":Be(o);break;case"clear-element":t.selectedElement=null,I();break;case"clear-screenshot":t.screenshot=null,I();break}}function J(){let e=x.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${t.connected?"connected":"disconnected"}`)}function R(){x.querySelectorAll(".om-pill-btn").forEach(e=>{let o=e.dataset.action;e.classList.toggle("active",o===t.activePanel||o==="select"&&t.selecting)})}function I(){let e=[];t.selectedElement&&e.push(`<span class="om-prompt-chip">${t.selectedElement.tagName}${t.selectedElement.id?"#"+t.selectedElement.id:""} <button class="om-prompt-chip-x" data-action="clear-element">${g.x}</button></span>`),t.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${g.x}</button></span>`),ve.innerHTML=e.join("")}function L(e){t.panelOpen=!0,t.activePanel=e,Q.classList.remove("om-hidden");let o=x.querySelector(".om-panel-title");o&&(o.textContent=e==="settings"?"Settings":"Chat"),w(),R()}function we(){t.panelOpen=!1,t.activePanel="",Q.classList.add("om-hidden"),R()}function be(e){t.panelOpen&&t.activePanel===e?we():L(e)}function w(){t.activePanel==="settings"?v.innerHTML=ze():t.activePanel==="chat"&&(v.innerHTML=Ue(),O()),Ne()}function ze(){let e=Object.entries(C).map(([u,S])=>{let A=t.configuredProviders[u]||S.local?" \u2713":"";return`<option value="${u}" ${t.provider===u?"selected":""}>${S.name}${A}</option>`}).join(""),o=C[t.provider],n=o?o.models.map(u=>`<option value="${u.id}" ${t.model===u.id?"selected":""}>${u.name}</option>`).join(""):'<option value="">Select provider first</option>',a=o?.local||!1,r=o?.keyUrl||"",s=o?.keyPlaceholder||"Enter API key...",i=t.configuredProviders[t.provider]||!1,l=t.updateAvailable?`<div class="om-update-banner">v${t.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",d=i||a?`<div class="om-status om-status-success">${g.check} ${o?.name||"Provider"} connected</div>`:"",c=t.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':t.saveStatus==="saved"?`${g.check} Saved`:"Save",m=t.saveStatus==="saving"?"om-btn om-btn-saving":t.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",k=t.saveStatus==="saving"?"disabled":"",p="";return!a&&t.provider&&(i?p=`
375
+ </div>`}function Be(e){e.addEventListener("click",a=>{let s=a.target.closest("[data-action]");if(!s)return;a.preventDefault(),a.stopPropagation();let r=s.dataset.action;je(r,s)}),e.addEventListener("change",a=>{let s=a.target,r=s.dataset.field;r&&(r==="provider"?(t.provider=s.value,t.model=C[t.provider]?.models[0]?.id||"",t.hasApiKey=t.configuredProviders[t.provider]||C[t.provider]?.local||!1,t.saveStatus="",v()):r==="model"&&(t.model=s.value))}),M.addEventListener("keydown",a=>{a.key==="Enter"&&!a.shiftKey&&(a.preventDefault(),Me())});let o=e.querySelector(".om-file-input");o&&o.addEventListener("change",()=>{Y(o.files),o.value=""});let n=e.querySelector(".om-prompt-row");n&&(n.addEventListener("dragover",a=>{a.preventDefault(),n.style.borderColor="rgba(108, 92, 231, 0.5)"}),n.addEventListener("dragleave",()=>{n.style.borderColor=""}),n.addEventListener("drop",a=>{a.preventDefault(),n.style.borderColor="";let s=a.dataTransfer;s?.files?.length&&Y(s.files)}),M.addEventListener("paste",a=>{let s=a.clipboardData?.items;if(s){for(let r=0;r<s.length;r++)if(s[r].type.startsWith("image/")){let i=s[r].getAsFile();if(i){let l=new DataTransfer;l.items.add(i),Y(l.files)}}}})),le(a=>{a.type==="reconnected"&&(t.connected=!0,ee())})}function qe(e){return t.roots.length>0?t.roots[0]+"/"+e:e}async function Ie(e){let o=e.dataset.file,n=e.dataset.search,a=e.dataset.replace;if(!o||!n||!a)return;let s,r;try{s=Z(n),r=Z(a)}catch{t.messages.push({role:"system",content:`Failed to decode diff data for ${o}`}),v();return}let i=e.closest(".om-diff-card"),l=qe(o);if(i){let c=i.querySelector(".om-diff-actions");c&&(c.innerHTML='<span class="om-spinner"></span> Applying...')}try{let d=(await E("fs.read",{path:l}))?.payload?.content;if(!d)t.messages.push({role:"system",content:`Could not read ${o} \u2014 file may not exist at ${l}`});else{let p=d.split(s).length-1;if(p===0)t.messages.push({role:"system",content:`No matching code found in ${o}. The file may have changed since the suggestion was made.`});else if(p>1)t.messages.push({role:"system",content:`Found ${p} matches in ${o} \u2014 expected exactly 1. Edit not applied for safety.`});else{let k=await E("fs.write",{path:l,content:d.replace(s,r)});if(k?.payload?.ok===!1)t.messages.push({role:"system",content:`Write failed: ${o} - ${k.payload?.error||"unknown"}`});else{let m=i?.dataset.diffIdx;m!==void 0?t.messages[parseInt(m)]={role:"system",content:`Applied change to ${o}`}:t.messages.push({role:"system",content:`Applied change to ${o}`})}}}}catch(c){t.messages.push({role:"system",content:`Failed to apply: ${o} \u2014 ${c.message}`})}v(),H()}function ze(e){let o=e.dataset.idx;if(o!==void 0){let n=parseInt(o),s=t.messages[n]?.content.split("__")?.[3]||"file";t.messages[n]={role:"system",content:`Rejected change to ${s}`}}v(),H()}function je(e,o){switch(e){case"select":We();break;case"screenshot":Xe();break;case"chat":J("chat");break;case"settings":J("settings");break;case"close-panel":Le();break;case"prompt-send":Me();break;case"save-settings":Ge();break;case"get-key":{let n=o.dataset.url;n&&window.open(n,"_blank","noopener");break}case"change-key":{let n=x.querySelector("[data-key-change]");n&&n.classList.remove("om-hidden"),o.style.display="none";break}case"network":J("chat"),Ke();break;case"attach-image":Ve();break;case"remove-attachment":{let n=parseInt(o.dataset.idx||"0",10);t.attachments.splice(n,1),ne();break}case"apply-diff":Ie(o);break;case"reject-diff":ze(o);break;case"clear-element":t.selectedElement=null,R();break;case"clear-screenshot":t.screenshot=null,R();break}}function ee(){let e=x.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${t.connected?"connected":"disconnected"}`)}function A(){x.querySelectorAll(".om-pill-btn").forEach(e=>{let o=e.dataset.action;e.classList.toggle("active",o===t.activePanel||o==="select"&&t.selecting)})}function R(){let e=[];t.selectedElement&&e.push(`<span class="om-prompt-chip">${t.selectedElement.tagName}${t.selectedElement.id?"#"+t.selectedElement.id:""} <button class="om-prompt-chip-x" data-action="clear-element">${u.x}</button></span>`),t.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${u.x}</button></span>`),t.attachments.length&&e.push(`<span class="om-prompt-chip">${t.attachments.length} image${t.attachments.length>1?"s":""}</span>`),Ee.innerHTML=e.join("")}function T(e){t.panelOpen=!0,t.activePanel=e,oe.classList.remove("om-hidden");let o=x.querySelector(".om-panel-title");o&&(o.textContent=e==="settings"?"Settings":"Chat"),v(),A()}function Le(){t.panelOpen=!1,t.activePanel="",oe.classList.add("om-hidden"),A()}function J(e){t.panelOpen&&t.activePanel===e?Le():T(e)}function v(){t.activePanel==="settings"?w.innerHTML=Ue():t.activePanel==="chat"&&(w.innerHTML=Fe(),H()),Re()}function Ue(){let e=Object.entries(C).map(([g,S])=>{let D=t.configuredProviders[g]||S.local?" \u2713":"";return`<option value="${g}" ${t.provider===g?"selected":""}>${S.name}${D}</option>`}).join(""),o=C[t.provider],n=o?o.models.map(g=>`<option value="${g.id}" ${t.model===g.id?"selected":""}>${g.name}</option>`).join(""):'<option value="">Select provider first</option>',a=o?.local||!1,s=o?.keyUrl||"",r=o?.keyPlaceholder||"Enter API key...",i=t.configuredProviders[t.provider]||!1,l=t.updateAvailable?`<div class="om-update-banner">v${t.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",c=i||a?`<div class="om-status om-status-success">${u.check} ${o?.name||"Provider"} connected</div>`:"",d=t.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':t.saveStatus==="saved"?`${u.check} Saved`:"Save",p=t.saveStatus==="saving"?"om-btn om-btn-saving":t.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",k=t.saveStatus==="saving"?"disabled":"",m="";return!a&&t.provider&&(i?m=`
342
376
  <div class="om-field">
343
377
  <label class="om-label">API Key</label>
344
378
  <div class="om-key-configured">
345
- ${g.check} <span>Key configured</span>
379
+ ${u.check} <span>Key configured</span>
346
380
  <button class="om-btn-change-key" data-action="change-key">Change</button>
347
381
  </div>
348
382
  <div class="om-key-change-row om-hidden" data-key-change>
349
383
  <div class="om-key-row">
350
- <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" />
351
- ${r?`<button class="om-btn-get-key" data-action="get-key" data-url="${r}">${g.externalLink} Get key</button>`:""}
384
+ <input type="text" class="om-input om-key-input" data-field="apiKey" placeholder="${r}" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
385
+ ${s?`<button class="om-btn-get-key" data-action="get-key" data-url="${s}">${u.externalLink} Get key</button>`:""}
352
386
  </div>
353
387
  </div>
354
- </div>`:p=`
388
+ </div>`:m=`
355
389
  <div class="om-field">
356
390
  <label class="om-label">API Key</label>
357
391
  <div class="om-key-row">
358
- <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" />
359
- ${r?`<button class="om-btn-get-key" data-action="get-key" data-url="${r}">${g.externalLink} Get key</button>`:""}
392
+ <input type="text" class="om-input om-key-input" data-field="apiKey" placeholder="${r}" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
393
+ ${s?`<button class="om-btn-get-key" data-action="get-key" data-url="${s}">${u.externalLink} Get key</button>`:""}
360
394
  </div>
361
- ${r?`<div class="om-key-hint"><a data-action="get-key" data-url="${r}">Get your ${o?.name||""} API key here</a></div>`:""}
395
+ ${s?`<div class="om-key-hint"><a data-action="get-key" data-url="${s}">Get your ${o?.name||""} API key here</a></div>`:""}
362
396
  </div>`),`
363
397
  ${l}
364
398
  <div class="om-settings">
@@ -370,16 +404,23 @@
370
404
  <label class="om-label">Model</label>
371
405
  <select class="om-select" data-field="model"><option value="">Select Model...</option>${n}</select>
372
406
  </div>
373
- ${p}
374
- <button class="${m}" data-action="save-settings" ${k}>${c}</button>
375
- ${d}
376
- </div>`}function Ue(){if(!t.provider||!t.hasApiKey&&!C[t.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=t.messages.map((a,r)=>{if(a.content.startsWith("__DIFF__"))try{let s=JSON.parse(W(a.content.slice(8))),i=X(s.search),l=X(s.replace);return`<div class="om-diff-card" data-diff-idx="${r}">
377
- <div class="om-diff-file">${M(s.file)}</div>
378
- <div class="om-diff-removed">${M(s.search.slice(0,200))}</div>
379
- <div class="om-diff-added">${M(s.replace.slice(0,200))}</div>
407
+ ${m}
408
+ <button class="${p}" data-action="save-settings" ${k}>${d}</button>
409
+ ${c}
410
+ </div>`}function Fe(){if(!t.provider||!t.hasApiKey&&!C[t.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=t.messages.map((a,s)=>{if(a.content.startsWith("__DIFF__"))try{let r=JSON.parse(Z(a.content.slice(8))),i=Q(r.search),l=Q(r.replace);return`<div class="om-diff-card" data-diff-idx="${s}">
411
+ <div class="om-diff-file">${L(r.file)}</div>
412
+ <div class="om-diff-removed">${L(r.search.slice(0,200))}</div>
413
+ <div class="om-diff-added">${L(r.replace.slice(0,200))}</div>
380
414
  <div class="om-diff-actions">
381
- <button class="om-btn om-btn-sm" data-action="apply-diff" data-file="${M(s.file)}" data-search="${i}" data-replace="${l}">Apply</button>
382
- <button class="om-btn-secondary om-btn-sm" data-action="reject-diff" data-idx="${r}">Reject</button>
415
+ <button class="om-btn om-btn-sm" data-action="apply-diff" data-file="${L(r.file)}" data-search="${i}" data-replace="${l}">Apply</button>
416
+ <button class="om-btn-secondary om-btn-sm" data-action="reject-diff" data-idx="${s}">Reject</button>
383
417
  </div>
384
- </div>`}catch{return'<div class="om-msg om-msg-system">Malformed diff data</div>'}return`<div class="om-msg om-msg-${a.role}">${M(a.content)}</div>`}).join(""),o=t.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${M(t.streamContent)}</div>`:"";return`<div class="om-chat-messages">${!t.messages.length&&!t.streaming?'<div class="om-chat-empty">Select an element or type below to start</div>':""}${e}${o}</div>`}function O(){requestAnimationFrame(()=>{let e=v.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function je(){let o=v.querySelector('[data-field="apiKey"]')?.value||"";if(!t.provider){t.saveStatus="error",B(),setTimeout(()=>{t.saveStatus="",w()},2e3);return}if(!ae()){t.saveStatus="error",B();let a=v.querySelector('[data-action="save-settings"]');a&&(a.innerHTML="Not connected - check terminal"),setTimeout(()=>{t.saveStatus="",w()},3e3);return}let n={provider:t.provider,model:t.model};o&&(n.apiKey=o),t.saveStatus="saving",B();try{let a=await Promise.race([E("config.set",n),new Promise((r,s)=>setTimeout(()=>s(new Error("Save timed out")),8e3))]);o&&t.provider&&(t.configuredProviders[t.provider]=!0),t.hasApiKey=!!(o||t.configuredProviders[t.provider]),t.saveStatus="saved",B(),setTimeout(()=>{t.saveStatus="",t.activePanel==="settings"&&L("chat")},1200)}catch(a){t.saveStatus="error";let r=v.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(()=>{t.saveStatus="",w()},4e3)}}function B(){let e=v.querySelector('[data-action="save-settings"]');e&&(t.saveStatus==="saving"?(e.innerHTML='<span class="om-spinner"></span> Saving...',e.className="om-btn om-btn-saving",e.disabled=!0):t.saveStatus==="saved"?(e.innerHTML=`${g.check} Saved`,e.className="om-btn om-btn-saved",e.disabled=!1):t.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=$.value.trim();if(!e||t.streaming)return;if(!t.provider||!t.hasApiKey&&!C[t.provider]?.local){L("settings");return}t.messages.push({role:"user",content:e}),t.streaming=!0,t.streamContent="",$.value="",L("chat");let o=he(t.selectedElement,t.screenshot);o.pageUrl=window.location.href,o.pageTitle=document.title;let n=4,a=24e3,r=/\.(?:[cm]?[jt]sx?|svelte|vue|astro|html?|css|scss|less|php|py)$/i;try{let s=await E("fs.list",{});s?.payload?.projectTree&&(o.projectTree=s.payload.projectTree);let l=(s?.payload?.files||[]).filter(p=>p.type==="file"&&r.test(p.path)),d=[e,t.selectedElement?.tagName,t.selectedElement?.id,t.selectedElement?.className,t.selectedElement?.textContent].filter(Boolean).join(" ").toLowerCase().split(/[^a-z0-9_-]+/).filter(p=>p.length>=2),c=l.map(p=>{let u=0,S=p.path.toLowerCase();for(let H of d)S.includes(H)&&(u+=5);return/(component|page|route|app|src|view|template)/.test(S)&&(u+=2),{...p,score:u}}).sort((p,u)=>u.score-p.score),m=[],k=0;for(let p of c.slice(0,n)){if(k>=a)break;try{let u=t.roots[0]||"",S=await E("fs.read",{path:u?`${u}/${p.path}`:p.path}),H=String(S?.payload?.content||"");if(!H)continue;let A=H.slice(0,Math.min(8e3,a-k));m.push({path:p.path,content:A}),k+=A.length}catch{}}m.length&&(o.files=m)}catch{}try{let s=await oe("llm.chat",{provider:t.provider,model:t.model,messages:t.messages.map(i=>({role:i.role,content:i.content})),context:o},i=>{t.streamContent+=i;let l=v.querySelector(".om-msg-assistant:last-child");l&&(l.innerHTML=`<span class="om-spinner"></span>${M(t.streamContent)}`,O())});if(t.messages.push({role:"assistant",content:t.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),d=JSON.stringify({id:l,file:i.file,search:i.search,replace:i.replace});t.messages.push({role:"system",content:`__DIFF__${X(d)}`})}}}catch(s){t.messages.push({role:"system",content:`Error: ${s.message}`})}t.streaming=!1,t.streamContent="",w(),O()}var _=null,N=null;function Ge(){t.selecting?Y():z()}function z(){t.selecting=!0,document.body.style.cursor="crosshair",R(),N=o=>{let n=o.target;if(n.closest("openmagic-toolbar")||n.dataset?.openmagic)return;let a=n.getBoundingClientRect();re({x:a.x,y:a.y,width:a.width,height:a.height})},_=o=>{o.preventDefault(),o.stopPropagation();let n=o.target;n.closest("openmagic-toolbar")||n.dataset?.openmagic||(t.selectedElement=se(n),Y(),I(),$.focus())};let e=o=>{o.key==="Escape"&&Y()};document.addEventListener("mousemove",N,!0),document.addEventListener("click",_,!0),document.addEventListener("keydown",e,!0),z._escHandler=e}function Y(){t.selecting=!1,document.body.style.cursor="",ie(),N&&(document.removeEventListener("mousemove",N,!0),N=null),_&&(document.removeEventListener("click",_,!0),_=null);let e=z._escHandler;e&&(document.removeEventListener("keydown",e,!0),z._escHandler=null),R()}async function Ke(){let e;try{let n=t.selectedElement?.cssSelector?.trim();n&&(e=document.querySelector(n)||void 0)}catch{}let o=await le(e||void 0);o&&(t.screenshot=o,I(),$.focus())}function Fe(){let e=!1,o=0,n=0,a=0,r=0;f.addEventListener("mousedown",s=>{let i=s.target;if(i.closest("[data-action]")||!i.closest(".om-grab")&&!i.closest(".om-pill-brand"))return;e=!0,o=s.clientX,n=s.clientY;let l=f.getBoundingClientRect();a=l.left,r=l.top,s.preventDefault()}),document.addEventListener("mousemove",s=>{e&&(f.style.left=a+s.clientX-o+"px",f.style.top=r+s.clientY-n+"px",f.style.right="auto",f.style.bottom="auto")}),document.addEventListener("mouseup",()=>{if(e){e=!1;try{localStorage.setItem("__om_pos__",JSON.stringify({left:f.style.left,top:f.style.top}))}catch{}}})}function M(e){let o=document.createElement("div");return o.textContent=e,o.innerHTML}function Ve(){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),n=xe.split(".").map(Number);for(let a=0;a<3;a++){if((o[a]||0)>(n[a]||0)){t.updateAvailable=!0,t.latestVersion=e.version,Xe();return}if((o[a]||0)<(n[a]||0))return}}).catch(()=>{})}function Xe(){if(x.querySelector(".om-update-dot"))return;let o=document.createElement("span");o.className="om-update-dot",o.title=`v${t.latestVersion} available`,o.addEventListener("click",()=>L("settings"));let n=x.querySelector(".om-toolbar-header");n&&n.appendChild(o)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",ye):ye());})();
418
+ </div>`}catch{return'<div class="om-msg om-msg-system">Malformed diff data</div>'}return`<div class="om-msg om-msg-${a.role}">${L(a.content)}</div>`}).join(""),o=t.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${L(t.streamContent)}</div>`:"";return`<div class="om-chat-messages">${!t.messages.length&&!t.streaming?'<div class="om-chat-empty">Select an element or type below to start</div>':""}${e}${o}</div>`}function H(){requestAnimationFrame(()=>{let e=w.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function Ge(){let o=w.querySelector('[data-field="apiKey"]')?.value||"";if(!t.provider){t.saveStatus="error",I(),setTimeout(()=>{t.saveStatus="",v()},2e3);return}if(!ce()){t.saveStatus="error",I();let a=w.querySelector('[data-action="save-settings"]');a&&(a.innerHTML="Not connected - check terminal"),setTimeout(()=>{t.saveStatus="",v()},3e3);return}let n={provider:t.provider,model:t.model};o&&(n.apiKey=o),t.saveStatus="saving",I();try{let a=await Promise.race([E("config.set",n),new Promise((s,r)=>setTimeout(()=>r(new Error("Save timed out")),8e3))]);o&&t.provider&&(t.configuredProviders[t.provider]=!0),t.hasApiKey=!!(o||t.configuredProviders[t.provider]),t.saveStatus="saved",I(),setTimeout(()=>{t.saveStatus="",t.activePanel==="settings"&&T("chat")},1200)}catch(a){t.saveStatus="error";let s=w.querySelector('[data-action="save-settings"]'),r=(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"}`;s&&(s.innerHTML=r,s.className="om-btn",s.disabled=!1),setTimeout(()=>{t.saveStatus="",v()},4e3)}}function I(){let e=w.querySelector('[data-action="save-settings"]');e&&(t.saveStatus==="saving"?(e.innerHTML='<span class="om-spinner"></span> Saving...',e.className="om-btn om-btn-saving",e.disabled=!0):t.saveStatus==="saved"?(e.innerHTML=`${u.check} Saved`,e.className="om-btn om-btn-saved",e.disabled=!1):t.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=M.value.trim();if(!e||t.streaming)return;if(!t.provider||!t.hasApiKey&&!C[t.provider]?.local){T("settings");return}t.messages.push({role:"user",content:e}),t.streaming=!0,t.streamContent="",M.value="",T("chat");let o=we(t.selectedElement,t.screenshot);o.pageUrl=window.location.href,o.pageTitle=document.title,t.attachments.length>0&&(o.screenshot||(o.screenshot=t.attachments[0]),o.attachments=[...t.attachments]);let n=4,a=24e3,s=/\.(?:[cm]?[jt]sx?|svelte|vue|astro|html?|css|scss|less|php|py)$/i;try{let r=await E("fs.list",{});r?.payload?.projectTree&&(o.projectTree=r.payload.projectTree);let l=(r?.payload?.files||[]).filter(m=>m.type==="file"&&s.test(m.path)),c=[e,t.selectedElement?.tagName,t.selectedElement?.id,t.selectedElement?.className,t.selectedElement?.textContent].filter(Boolean).join(" ").toLowerCase().split(/[^a-z0-9_-]+/).filter(m=>m.length>=2),d=l.map(m=>{let g=0,S=m.path.toLowerCase();for(let P of c)S.includes(P)&&(g+=5);return/(component|page|route|app|src|view|template)/.test(S)&&(g+=2),{...m,score:g}}).sort((m,g)=>g.score-m.score),p=[],k=0;for(let m of d.slice(0,n)){if(k>=a)break;try{let g=t.roots[0]||"",S=await E("fs.read",{path:g?`${g}/${m.path}`:m.path}),P=String(S?.payload?.content||"");if(!P)continue;let D=P.slice(0,Math.min(8e3,a-k));p.push({path:m.path,content:D}),k+=D.length}catch{}}p.length&&(o.files=p)}catch{}try{let r=await ie("llm.chat",{provider:t.provider,model:t.model,messages:t.messages.map(i=>({role:i.role,content:i.content})),context:o},i=>{t.streamContent+=i;let l=w.querySelector(".om-msg-assistant:last-child");l&&(l.innerHTML=`<span class="om-spinner"></span>${L(t.streamContent)}`,H())});if(t.messages.push({role:"assistant",content:t.streamContent||r?.content||""}),r?.modifications?.length){for(let i of r.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});t.messages.push({role:"system",content:`__DIFF__${Q(c)}`})}}}catch(r){t.messages.push({role:"system",content:`Error: ${r.message}`})}t.streaming=!1,t.streamContent="",t.attachments=[],ne(),v(),H()}function Ke(){let e=window.performance,o=e.getEntriesByType("navigation")[0],n=e.getEntriesByType("paint"),a=e.getEntriesByType("resource").slice(-20),s=W(),r=X(),i=[];i.push("--- Network & Performance Capture ---"),o&&(i.push(`Page load: ${Math.round(o.loadEventEnd-o.startTime)}ms`),i.push(`DOM ready: ${Math.round(o.domContentLoadedEventEnd-o.startTime)}ms`),i.push(`TTFB: ${Math.round(o.responseStart-o.startTime)}ms`));let l=n.find(c=>c.name==="first-contentful-paint");if(l&&i.push(`FCP: ${Math.round(l.startTime)}ms`),s.length){i.push(`
419
+ Recent requests (${s.length}):`);for(let c of s.slice(-15))i.push(` ${c.method} ${c.url.slice(0,80)} \u2192 ${c.status||"pending"} (${c.duration||"?"}ms)`)}if(r.length){let c=r.filter(p=>p.level==="error"),d=r.filter(p=>p.level==="warn");c.length&&i.push(`
420
+ Console errors: ${c.length}`),d.length&&i.push(`Console warnings: ${d.length}`)}if(a.length){let c=[...a].sort((d,p)=>p.duration-d.duration).slice(0,5);i.push(`
421
+ Slowest resources:`);for(let d of c)i.push(` ${Math.round(d.duration)}ms \u2014 ${d.name.split("/").pop()?.slice(0,50)}`)}t.messages.push({role:"system",content:i.join(`
422
+ `)}),v(),H(),R()}function Ve(){let e=x.querySelector(".om-file-input");e&&e.click()}function Y(e){if(e)for(let o=0;o<e.length&&t.attachments.length<5;o++){let n=e[o];if(!n.type.startsWith("image/")||n.size>10*1024*1024)continue;let a=new FileReader;a.onload=()=>{typeof a.result=="string"&&(t.attachments.push(a.result),ne())},a.readAsDataURL(n)}}function ne(){let e=x.querySelector(".om-prompt-attachments");if(e){if(!t.attachments.length){e.innerHTML="",e.classList.add("om-hidden");return}e.classList.remove("om-hidden"),e.innerHTML=t.attachments.map((o,n)=>`<div class="om-attachment-thumb">
423
+ <img src="${o}" alt="attachment" />
424
+ <button class="om-attachment-remove" data-action="remove-attachment" data-idx="${n}">${u.x}</button>
425
+ </div>`).join("")}}var N=null,O=null;function We(){t.selecting?te():z()}function z(){t.selecting=!0,document.body.style.cursor="crosshair",A(),O=o=>{let n=o.target;if(n.closest("openmagic-toolbar")||n.dataset?.openmagic)return;let a=n.getBoundingClientRect();pe({x:a.x,y:a.y,width:a.width,height:a.height})},N=o=>{o.preventDefault(),o.stopPropagation();let n=o.target;n.closest("openmagic-toolbar")||n.dataset?.openmagic||(t.selectedElement=de(n),te(),R(),M.focus())};let e=o=>{o.key==="Escape"&&te()};document.addEventListener("mousemove",O,!0),document.addEventListener("click",N,!0),document.addEventListener("keydown",e,!0),z._escHandler=e}function te(){t.selecting=!1,document.body.style.cursor="",me(),O&&(document.removeEventListener("mousemove",O,!0),O=null),N&&(document.removeEventListener("click",N,!0),N=null);let e=z._escHandler;e&&(document.removeEventListener("keydown",e,!0),z._escHandler=null),A()}async function Xe(){let e;try{let n=t.selectedElement?.cssSelector?.trim();n&&(e=document.querySelector(n)||void 0)}catch{}let o=await ue(e||void 0);o&&(t.screenshot=o,R(),M.focus())}function Je(){let e=!1,o=0,n=0,a=0,s=0;h.addEventListener("mousedown",r=>{let i=r.target;if(i.closest("[data-action]")||!i.closest(".om-grab")&&!i.closest(".om-pill-brand"))return;e=!0,o=r.clientX,n=r.clientY;let l=h.getBoundingClientRect();a=l.left,s=l.top,r.preventDefault()}),document.addEventListener("mousemove",r=>{e&&(h.style.left=a+r.clientX-o+"px",h.style.top=s+r.clientY-n+"px",h.style.right="auto",h.style.bottom="auto")}),document.addEventListener("mouseup",()=>{if(e){e=!1;try{localStorage.setItem("__om_pos__",JSON.stringify({left:h.style.left,top:h.style.top}))}catch{}}})}function L(e){let o=document.createElement("div");return o.textContent=e,o.innerHTML}function Ye(){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),n=Se.split(".").map(Number);for(let a=0;a<3;a++){if((o[a]||0)>(n[a]||0)){t.updateAvailable=!0,t.latestVersion=e.version,Qe();return}if((o[a]||0)<(n[a]||0))return}}).catch(()=>{})}function Qe(){if(x.querySelector(".om-update-dot"))return;let o=document.createElement("span");o.className="om-update-dot",o.title=`v${t.latestVersion} available`,o.addEventListener("click",()=>T("settings"));let n=x.querySelector(".om-toolbar-header");n&&n.appendChild(o)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",ke):ke());})();
385
426
  //# sourceMappingURL=index.global.js.map