openmagic 0.10.0 → 0.12.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 B=`
2
+ "use strict";var OpenMagicToolbar=(()=>{var K=`
3
3
  :host {
4
4
  all: initial;
5
5
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
@@ -17,7 +17,7 @@
17
17
  bottom: 20px;
18
18
  right: 20px;
19
19
  z-index: 2147483647;
20
- width: 420px;
20
+ width: min(420px, calc(100vw - 40px));
21
21
  display: flex;
22
22
  flex-direction: column;
23
23
  background: #111125;
@@ -27,6 +27,23 @@
27
27
  overflow: hidden;
28
28
  }
29
29
 
30
+ /* Panel header */
31
+ .om-panel-header {
32
+ display: flex; align-items: center; gap: 6px;
33
+ padding: 8px 12px;
34
+ border-bottom: 1px solid rgba(255,255,255,0.04);
35
+ background: rgba(108, 92, 231, 0.03);
36
+ flex-shrink: 0;
37
+ }
38
+ .om-panel-title { font-size: 11px; font-weight: 600; color: #a29bfe; }
39
+ .om-panel-version { font-size: 10px; color: #444; margin-left: auto; }
40
+ .om-panel-close {
41
+ background: none; border: none; color: #555; cursor: pointer;
42
+ padding: 2px 4px; border-radius: 4px; line-height: 1;
43
+ display: flex; align-items: center;
44
+ }
45
+ .om-panel-close:hover { color: #ccc; background: rgba(255,255,255,0.05); }
46
+
30
47
  /* \u2500\u2500 Header Bar (brand + tools) \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 */
31
48
  .om-toolbar-header {
32
49
  display: flex;
@@ -246,54 +263,66 @@
246
263
  font-family: 'SF Mono', 'Fira Code', Consolas, monospace;
247
264
  font-size: 10px; color: #555; max-height: 60px; overflow-y: auto; margin-bottom: 6px;
248
265
  }
249
- `;var p=null,m=new Map,ge=[],N=[],y=!1,U=!1,P=null;function _(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function O(e,t){return U=!0,new Promise((o,n)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,n(new Error("Handshake timeout")),p?.close())},1e4);try{p=new WebSocket(`ws://127.0.0.1:${e}/__openmagic__/ws`),p.onopen=()=>{let r=_();p.send(JSON.stringify({id:r,type:"handshake",payload:{token:t}})),m.set(r,l=>{if(l.type==="handshake.ok"){clearTimeout(i),y=!0;for(let f of N)p?.send(f);N=[],s||(s=!0,o())}else l.type==="error"&&(clearTimeout(i),s||(s=!0,n(new Error(l.payload?.message||"Handshake failed"))))})},p.onmessage=r=>{try{let l=JSON.parse(r.data);l.id&&m.has(l.id)&&(m.get(l.id)(l),(l.type==="llm.done"||l.type==="llm.error"||!l.type.startsWith("llm."))&&m.delete(l.id));for(let f of ge)f(l)}catch{}},p.onclose=()=>{let r=y;if(y=!1,!r&&!s){clearTimeout(i),s=!0,n(new Error("WebSocket closed before handshake"));return}r&&U&&!P&&(P=setTimeout(()=>{P=null,O(e,t).catch(()=>{})},2e3))},p.onerror=()=>{!y&&!s&&(clearTimeout(i),s=!0,n(new Error("WebSocket connection failed")))}}catch(r){clearTimeout(i),s||(s=!0,n(r))}})}function z(e){let t=JSON.stringify(e);p&&p.readyState===WebSocket.OPEN&&y?p.send(t):N.push(t)}function k(e,t){return new Promise((o,n)=>{let s=_(),i=setTimeout(()=>{m.delete(s),n(new Error("Request timeout"))},3e4);m.set(s,r=>{clearTimeout(i),r.type==="error"?n(new Error(r.payload?.message||"Unknown error")):o(r)}),z({id:s,type:e,payload:t})})}function G(e,t,o){return new Promise((n,s)=>{let i=_(),r=setTimeout(()=>{m.delete(i),s(new Error("Stream timeout"))},12e4);m.set(i,l=>{l.type==="llm.chunk"?o(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(r),m.delete(i),n(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(r),m.delete(i),s(new Error(l.payload?.message||"Stream error")))}),z({id:i,type:e,payload:t})})}function I(){return y}var fe=["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 K(e){let t=window.getComputedStyle(e),o={};for(let s of fe)o[s]=t.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:be(e),cssSelector:ye(e),xpath:xe(e),computedStyles:o,rect:{x:n.x,y:n.y,width:n.width,height:n.height}}}function be(e){let t=e.cloneNode(!0);t.querySelectorAll("script, style, svg").forEach(s=>s.remove());let n=t.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(`
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 u=null,g=new Map,E=[],q=[],w=!1,F=!1,A=null;function B(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function I(e,t){return F=!0,new Promise((o,n)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,n(new Error("Handshake timeout")),u?.close())},1e4);try{let r=window.location.hostname||"127.0.0.1";u=new WebSocket(`ws://${r}:${e}/__openmagic__/ws`),u.onopen=()=>{let l=B();u.send(JSON.stringify({id:l,type:"handshake",payload:{token:t}})),g.set(l,c=>{if(c.type==="handshake.ok"){clearTimeout(i),w=!0;for(let h of q)u?.send(h);q=[],s||(s=!0,o())}else c.type==="error"&&(clearTimeout(i),s||(s=!0,n(new Error(c.payload?.message||"Handshake failed"))))})},u.onmessage=l=>{try{let c=JSON.parse(l.data);c.id&&g.has(c.id)&&(g.get(c.id)(c),(c.type==="llm.done"||c.type==="llm.error"||!c.type.startsWith("llm."))&&g.delete(c.id));for(let h of E)h(c)}catch{}},u.onclose=()=>{let l=w;if(w=!1,!l&&!s){clearTimeout(i),s=!0,n(new Error("WebSocket closed before handshake"));return}l&&F&&!A&&(A=setTimeout(()=>{A=null,I(e,t).then(()=>{for(let c of E)c({type:"reconnected",payload:{}})}).catch(()=>{})},2e3))},u.onerror=()=>{!w&&!s&&(clearTimeout(i),s=!0,n(new Error("WebSocket connection failed")))}}catch(r){clearTimeout(i),s||(s=!0,n(r))}})}function V(e){let t=JSON.stringify(e);u&&u.readyState===WebSocket.OPEN&&w?u.send(t):q.push(t)}function k(e,t){return new Promise((o,n)=>{let s=B(),i=setTimeout(()=>{g.delete(s),n(new Error("Request timeout"))},3e4);g.set(s,r=>{clearTimeout(i),r.type==="error"?n(new Error(r.payload?.message||"Unknown error")):o(r)}),V({id:s,type:e,payload:t})})}function W(e,t,o){return new Promise((n,s)=>{let i=B(),r=setTimeout(()=>{g.delete(i),s(new Error("Stream timeout"))},12e4);g.set(i,l=>{l.type==="llm.chunk"?o(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(r),g.delete(i),n(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(r),g.delete(i),s(new Error(l.payload?.message||"Stream error")))}),V({id:i,type:e,payload:t})})}function X(e){return E.push(e),()=>{E=E.filter(t=>t!==e)}}function J(){return w}var ye=["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 Y(e){let t=window.getComputedStyle(e),o={};for(let s of ye)o[s]=t.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:xe(e),cssSelector:ve(e),xpath:we(e),computedStyles:o,rect:{x:n.x,y:n.y,width:n.width,height:n.height}}}function xe(e){let t=e.cloneNode(!0);t.querySelectorAll("script, style, svg").forEach(s=>s.remove());let n=t.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(`
250
279
  `);n=`<${s} ${i}>
251
280
  ${r}
252
281
  ${e.children.length>5?`<!-- +${e.children.length-5} more children -->`:""}
253
- </${s}>`}return n}function ye(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=[],o=e;for(;o&&o!==document.body;){let n=o.tagName.toLowerCase();if(o.id){t.unshift(`#${CSS.escape(o.id)}`);break}if(o.className&&typeof o.className=="string"){let i=o.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=o.parentElement;if(s){let i=Array.from(s.children).filter(r=>r.tagName===o.tagName);if(i.length>1){let r=i.indexOf(o)+1;n+=`:nth-of-type(${r})`}}t.unshift(n),o=o.parentElement}return t.join(" > ")}function xe(e){let t=[],o=e;for(;o&&o!==document;){if(o.nodeType===Node.ELEMENT_NODE){let n=o,s=1,i=n.previousElementSibling;for(;i;)i.tagName===n.tagName&&s++,i=i.previousElementSibling;t.unshift(`${n.tagName.toLowerCase()}[${s}]`)}o=o.parentNode}return"/"+t.join("/")}var d=null;function j(e){d||(d=document.createElement("div"),d.style.cssText=`
282
+ </${s}>`}return n}function ve(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=[],o=e;for(;o&&o!==document.body;){let n=o.tagName.toLowerCase();if(o.id){t.unshift(`#${CSS.escape(o.id)}`);break}if(o.className&&typeof o.className=="string"){let i=o.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=o.parentElement;if(s){let i=Array.from(s.children).filter(r=>r.tagName===o.tagName);if(i.length>1){let r=i.indexOf(o)+1;n+=`:nth-of-type(${r})`}}t.unshift(n),o=o.parentElement}return t.join(" > ")}function we(e){let t=[],o=e;for(;o&&o!==document;){if(o.nodeType===Node.ELEMENT_NODE){let n=o,s=1,i=n.previousElementSibling;for(;i;)i.tagName===n.tagName&&s++,i=i.previousElementSibling;t.unshift(`${n.tagName.toLowerCase()}[${s}]`)}o=o.parentNode}return"/"+t.join("/")}var m=null;function Q(e){m||(m=document.createElement("div"),m.style.cssText=`
254
283
  position: fixed;
255
284
  pointer-events: none;
256
285
  z-index: 2147483646;
257
286
  border: 2px solid #6c5ce7;
258
287
  background: rgba(108, 92, 231, 0.1);
259
288
  transition: all 0.1s ease;
260
- `,d.dataset.openmagic="highlight",document.body.appendChild(d)),d.style.left=`${e.x}px`,d.style.top=`${e.y}px`,d.style.width=`${e.width}px`,d.style.height=`${e.height}px`,d.style.display="block"}function V(){d&&(d.style.display="none")}async function F(e){try{return e?await we(e):await ve()}catch(t){return console.warn("[OpenMagic] Screenshot capture failed:",t),null}}async function ve(){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 n=await W(document.body),s=await Y(n,window.innerWidth,window.innerHeight);return o.drawImage(s,0,0),e.toDataURL("image/png")}catch{return null}}async function we(e){let t=e.getBoundingClientRect(),o=document.createElement("canvas"),n=window.devicePixelRatio||1;o.width=t.width*n,o.height=t.height*n;let s=o.getContext("2d");s.scale(n,n);try{let i=await W(e),r=await Y(i,t.width,t.height);return s.drawImage(r,0,0),o.toDataURL("image/png")}catch{return null}}function W(e){return new Promise(t=>{let o=e.cloneNode(!0);X(e,o);let n=e.getBoundingClientRect(),s=n.width,i=n.height,r=`
289
+ `,m.dataset.openmagic="highlight",document.body.appendChild(m)),m.style.left=`${e.x}px`,m.style.top=`${e.y}px`,m.style.width=`${e.width}px`,m.style.height=`${e.height}px`,m.style.display="block"}function Z(){m&&(m.style.display="none")}async function ee(e){try{return e?await Se(e):await ke()}catch(t){return console.warn("[OpenMagic] Screenshot capture failed:",t),null}}async function ke(){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 n=await te(document.body),s=await ne(n,window.innerWidth,window.innerHeight);return o.drawImage(s,0,0),e.toDataURL("image/png")}catch{return null}}async function Se(e){let t=e.getBoundingClientRect(),o=document.createElement("canvas"),n=window.devicePixelRatio||1;o.width=t.width*n,o.height=t.height*n;let s=o.getContext("2d");s.scale(n,n);try{let i=await te(e),r=await ne(i,t.width,t.height);return s.drawImage(r,0,0),o.toDataURL("image/png")}catch{return null}}function te(e){return new Promise(t=>{let o=e.cloneNode(!0);oe(e,o);let n=e.getBoundingClientRect(),s=n.width,i=n.height,r=`
261
290
  <svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${i}">
262
291
  <foreignObject width="100%" height="100%">
263
292
  <div xmlns="http://www.w3.org/1999/xhtml" style="width:${s}px;height:${i}px;overflow:hidden;">
264
293
  ${o.outerHTML}
265
294
  </div>
266
295
  </foreignObject>
267
- </svg>`;t(r)})}function X(e,t){let o=window.getComputedStyle(e),n="";for(let r=0;r<o.length;r++){let l=o[r];n+=`${l}:${o.getPropertyValue(l)};`}t.style.cssText=n;let s=e.children,i=t.children;for(let r=0;r<s.length&&r<i.length;r++)X(s[r],i[r])}function Y(e,t,o){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=t,i.height=o,i.src=l})}var E=[];var J=!1;function Z(){if(J)return;J=!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,R(i),r}catch(r){throw i.status=0,i.duration=Date.now()-i.timestamp,R(i),r}};let t=XMLHttpRequest.prototype.open,o=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,s,...i){return this.__om_method=n,this.__om_url=s,this.__om_start=Date.now(),t.apply(this,[n,s,...i])},XMLHttpRequest.prototype.send=function(...n){return this.addEventListener("loadend",()=>{R({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,n)}}function R(e){e.url.includes("__openmagic__")||(E.push(e),E.length>50&&E.shift())}function ke(){return[...E]}var T=[],Se=100,Q=!1;function ee(){if(Q)return;Q=!0;let e=["log","warn","error","info","debug"];for(let t of e){let o=console[t];console[t]=function(...n){T.push({level:t,args:n.map(s=>{try{return typeof s=="object"?JSON.stringify(s).slice(0,500):String(s)}catch{return String(s)}}),timestamp:Date.now()}),T.length>Se&&T.shift(),o.apply(console,n)}}}function Le(){return[...T]}function te(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:ke().map(o=>({method:o.method,url:o.url,status:o.status,duration:o.duration,timestamp:o.timestamp})),consoleLogs:Le().map(o=>({level:o.level,args:o.args,timestamp:o.timestamp}))}}var c={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>'},H={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:[]}},ie="0.10.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:""},g,h,v,re,q,u;function oe(){if(document.querySelector("openmagic-toolbar"))return;let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",g=e.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=B,g.appendChild(t);let o=document.createElement("div");g.appendChild(o),o.innerHTML=Me(),h=o.querySelector(".om-toolbar"),v=o.querySelector(".om-prompt-input"),re=o.querySelector(".om-prompt-context"),q=o.querySelector(".om-panel"),u=o.querySelector(".om-panel-body"),document.body.appendChild(e),Ee(o),Oe(),Z(),ee(),Re();let n=window.__OPENMAGIC_CONFIG__;n&&O(n.wsPort,n.token).then(()=>(a.connected=!0,ne(),k("config.get"))).then(s=>{a.provider=s.payload?.provider||"",a.model=s.payload?.model||"",a.hasApiKey=s.payload?.hasApiKey||!1,a.roots=s.payload?.roots||[],(!a.provider||!a.hasApiKey)&&w("settings"),M()}).catch(()=>{a.connected=!1,ne()})}function Me(){return`
296
+ </svg>`;t(r)})}function oe(e,t){let o=window.getComputedStyle(e),n="";for(let r=0;r<o.length;r++){let l=o[r];n+=`${l}:${o.getPropertyValue(l)};`}t.style.cssText=n;let s=e.children,i=t.children;for(let r=0;r<s.length&&r<i.length;r++)oe(s[r],i[r])}function ne(e,t,o){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=t,i.height=o,i.src=l})}var _=[];var ae=!1;function ie(){if(ae)return;ae=!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,z(i),r}catch(r){throw i.status=0,i.duration=Date.now()-i.timestamp,z(i),r}};let t=XMLHttpRequest.prototype.open,o=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,s,...i){return this.__om_method=n,this.__om_url=s,this.__om_start=Date.now(),t.apply(this,[n,s,...i])},XMLHttpRequest.prototype.send=function(...n){return this.addEventListener("loadend",()=>{z({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,n)}}function z(e){e.url.includes("__openmagic__")||(_.push(e),_.length>50&&_.shift())}function Me(){return[..._]}var P=[],Ee=100,se=!1;function re(){if(se)return;se=!0;let e=["log","warn","error","info","debug"];for(let t of e){let o=console[t];console[t]=function(...n){P.push({level:t,args:n.map(s=>{try{return typeof s=="object"?JSON.stringify(s).slice(0,500):String(s)}catch{return String(s)}}),timestamp:Date.now()}),P.length>Ee&&P.shift(),o.apply(console,n)}}}function Le(){return[...P]}function le(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:Me().map(o=>({method:o.method,url:o.url,status:o.status,duration:o.duration,timestamp:o.timestamp})),consoleLogs:Le().map(o=>({level:o.level,args:o.args,timestamp:o.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>'},O={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:[]}},me="0.12.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:""},b,p,S,ue,G,f;function ce(){if(document.querySelector("openmagic-toolbar"))return;let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",b=e.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=K,b.appendChild(t);let o=document.createElement("div");b.appendChild(o),o.innerHTML=Te(),p=o.querySelector(".om-toolbar"),S=o.querySelector(".om-prompt-input"),ue=o.querySelector(".om-prompt-context"),G=o.querySelector(".om-panel"),f=o.querySelector(".om-panel-body"),document.body.appendChild(e),Ce(o),Ae();try{let i=JSON.parse(localStorage.getItem("__om_pos__")||"");i?.left&&i?.top&&(p.style.left=i.left,p.style.top=i.top,p.style.right="auto",p.style.bottom="auto")}catch{}ie(),re(),qe();let n=window.__OPENMAGIC_TOKEN__,s=parseInt(window.location.port,10)||(window.location.protocol==="https:"?443:80);n&&I(s,n).then(()=>(a.connected=!0,U(),k("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)&&M("settings"),$()}).catch(()=>{a.connected=!1,U()})}function Te(){return`
268
297
  <div class="om-toolbar">
269
298
  <div class="om-toolbar-header">
270
- <span class="om-grab">${c.grip}</span>
299
+ <span class="om-grab">${d.grip}</span>
271
300
  <span class="om-pill-brand">
272
- <span class="om-pill-icon">${c.sparkle}</span>
301
+ <span class="om-pill-icon">${d.sparkle}</span>
273
302
  <span class="om-pill-text">OpenMagic</span>
274
303
  </span>
275
304
  <span class="om-pill-divider"></span>
276
- <button class="om-pill-btn" data-action="select" title="Select element">${c.crosshair}</button>
277
- <button class="om-pill-btn" data-action="screenshot" title="Screenshot">${c.camera}</button>
305
+ <button class="om-pill-btn" data-action="select" title="Select element">${d.crosshair}</button>
306
+ <button class="om-pill-btn" data-action="screenshot" title="Screenshot">${d.camera}</button>
278
307
  <span class="om-pill-divider"></span>
279
- <button class="om-pill-btn" data-action="chat" title="Chat">${c.chat}</button>
280
- <button class="om-pill-btn" data-action="settings" title="Settings">${c.settings}</button>
308
+ <button class="om-pill-btn" data-action="chat" title="Chat">${d.chat}</button>
309
+ <button class="om-pill-btn" data-action="settings" title="Settings">${d.settings}</button>
281
310
  <span class="om-status-dot disconnected"></span>
282
311
  </div>
283
312
  <div class="om-panel om-hidden">
284
313
  <div class="om-panel-header">
285
314
  <span class="om-panel-title"></span>
286
- <span class="om-panel-version">v${ie}</span>
287
- <button class="om-panel-close" data-action="close-panel">${c.x}</button>
315
+ <span class="om-panel-version">v${me}</span>
316
+ <button class="om-panel-close" data-action="close-panel">${d.x}</button>
288
317
  </div>
289
318
  <div class="om-panel-body"></div>
290
319
  </div>
291
320
  <div class="om-prompt-row">
292
321
  <div class="om-prompt-context"></div>
293
322
  <input class="om-prompt-input" type="text" placeholder="Describe what to change..." autocomplete="off" />
294
- <button class="om-prompt-send" data-action="prompt-send">${c.send}</button>
323
+ <button class="om-prompt-send" data-action="prompt-send">${d.send}</button>
295
324
  </div>
296
- </div>`}function Ee(e){e.addEventListener("click",t=>{let o=t.target.closest("[data-action]");if(!o)return;t.preventDefault(),t.stopPropagation();let n=o.dataset.action;Te(n,o)}),e.addEventListener("change",t=>{let o=t.target,n=o.dataset.field;n&&(n==="provider"?(a.provider=o.value,a.model="",a.saveStatus="",x()):n==="model"&&(a.model=o.value))}),v.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),ce())})}function Te(e,t){switch(e){case"select":Pe();break;case"screenshot":_e();break;case"chat":ae("chat");break;case"settings":ae("settings");break;case"close-panel":le();break;case"prompt-send":ce();break;case"save-settings":$e();break;case"get-key":{let o=t.dataset.url;o&&window.open(o,"_blank","noopener");break}case"clear-element":a.selectedElement=null,$();break;case"clear-screenshot":a.screenshot=null,$();break}}function ne(){let e=g.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${a.connected?"connected":"disconnected"}`)}function M(){g.querySelectorAll(".om-pill-btn").forEach(e=>{let t=e.dataset.action;e.classList.toggle("active",t===a.activePanel||t==="select"&&a.selecting)})}function $(){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">${c.x}</button></span>`),a.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${c.x}</button></span>`),re.innerHTML=e.join("")}function w(e){a.panelOpen=!0,a.activePanel=e,q.classList.remove("om-hidden");let t=g.querySelector(".om-panel-title");t&&(t.textContent=e==="settings"?"Settings":"Chat"),x(),M()}function le(){a.panelOpen=!1,a.activePanel="",q.classList.add("om-hidden"),M()}function ae(e){a.panelOpen&&a.activePanel===e?le():w(e)}function x(){a.activePanel==="settings"?u.innerHTML=Ce():a.activePanel==="chat"&&(u.innerHTML=He(),A())}function Ce(){let e=Object.entries(H).map(([b,ue])=>`<option value="${b}" ${a.provider===b?"selected":""}>${ue.name}</option>`).join(""),t=H[a.provider],o=t?t.models.map(b=>`<option value="${b.id}" ${a.model===b.id?"selected":""}>${b.name}</option>`).join(""):'<option value="">Select provider first</option>',n=t?.local||!1,s=t?.keyUrl||"",i=t?.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">${c.check} Connected</div>`:"",f=a.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':a.saveStatus==="saved"?`${c.check} Saved`:"Save",pe=a.saveStatus==="saving"?"om-btn om-btn-saving":a.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",me=a.saveStatus==="saving"?"disabled":"";return`
325
+ </div>`}function Ce(e){e.addEventListener("click",t=>{let o=t.target.closest("[data-action]");if(!o)return;t.preventDefault(),t.stopPropagation();let n=o.dataset.action;_e(n,o)}),e.addEventListener("change",t=>{let o=t.target,n=o.dataset.field;n&&(n==="provider"?(a.provider=o.value,a.model="",a.saveStatus="",y()):n==="model"&&(a.model=o.value))}),S.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),he())}),X(t=>{t.type==="reconnected"&&(a.connected=!0,U())})}function de(e){return a.roots.length>0?a.roots[0]+"/"+e:e}async function $e(e){let t=e.dataset.file,o=e.dataset.search,n=e.dataset.replace;if(!t||!o||!n)return;let s=atob(o),i=atob(n),r=e.closest(".om-diff-card");try{let c=(await k("fs.read",{path:de(t)})).payload?.content;if(c?.includes(s)){let h=await k("fs.write",{path:de(t),content:c.replace(s,i)});if(h?.payload?.ok===!1)a.messages.push({role:"system",content:`Write failed: ${t} - ${h.payload.error||"unknown"}`});else{let H=r?.dataset.diffIdx;H!==void 0&&(a.messages[parseInt(H)]={role:"system",content:`Applied change to ${t}`})}}else a.messages.push({role:"system",content:`Could not find matching code in ${t}`})}catch(l){a.messages.push({role:"system",content:`Failed: ${t} - ${l.message}`})}y(),C()}function He(e){let t=e.dataset.idx;if(t!==void 0){let o=parseInt(t),s=a.messages[o]?.content.split("__")?.[3]||"file";a.messages[o]={role:"system",content:`Rejected change to ${s}`}}y(),C()}function _e(e,t){switch(e){case"select":Re();break;case"screenshot":De();break;case"chat":pe("chat");break;case"settings":pe("settings");break;case"close-panel":ge();break;case"prompt-send":he();break;case"save-settings":Oe();break;case"get-key":{let o=t.dataset.url;o&&window.open(o,"_blank","noopener");break}case"apply-diff":$e(t);break;case"reject-diff":He(t);break;case"clear-element":a.selectedElement=null,R();break;case"clear-screenshot":a.screenshot=null,R();break}}function U(){let e=b.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${a.connected?"connected":"disconnected"}`)}function $(){b.querySelectorAll(".om-pill-btn").forEach(e=>{let t=e.dataset.action;e.classList.toggle("active",t===a.activePanel||t==="select"&&a.selecting)})}function R(){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>`),ue.innerHTML=e.join("")}function M(e){a.panelOpen=!0,a.activePanel=e,G.classList.remove("om-hidden");let t=b.querySelector(".om-panel-title");t&&(t.textContent=e==="settings"?"Settings":"Chat"),y(),$()}function ge(){a.panelOpen=!1,a.activePanel="",G.classList.add("om-hidden"),$()}function pe(e){a.panelOpen&&a.activePanel===e?ge():M(e)}function y(){a.activePanel==="settings"?f.innerHTML=Pe():a.activePanel==="chat"&&(f.innerHTML=Ne(),C())}function Pe(){let e=Object.entries(O).map(([v,fe])=>`<option value="${v}" ${a.provider===v?"selected":""}>${fe.name}</option>`).join(""),t=O[a.provider],o=t?t.models.map(v=>`<option value="${v.id}" ${a.model===v.id?"selected":""}>${v.name}</option>`).join(""):'<option value="">Select provider first</option>',n=t?.local||!1,s=t?.keyUrl||"",i=t?.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",h=a.saveStatus==="saving"?"om-btn om-btn-saving":a.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",H=a.saveStatus==="saving"?"disabled":"";return`
297
326
  ${r}
298
327
  <div class="om-settings">
299
328
  <div class="om-field">
@@ -308,11 +337,19 @@
308
337
  <label class="om-label">API Key</label>
309
338
  <div class="om-key-row">
310
339
  <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" />
311
- ${s?`<button class="om-btn-get-key" data-action="get-key" data-url="${s}">${c.externalLink} Get key</button>`:""}
340
+ ${s?`<button class="om-btn-get-key" data-action="get-key" data-url="${s}">${d.externalLink} Get key</button>`:""}
312
341
  </div>
313
342
  ${s?`<div class="om-key-hint"><a data-action="get-key" data-url="${s}">Get your ${t?.name||""} API key here</a></div>`:""}
314
343
  </div>
315
- <button class="${pe}" data-action="save-settings" ${me}>${f}</button>
344
+ <button class="${h}" data-action="save-settings" ${H}>${c}</button>
316
345
  ${l}
317
- </div>`}function He(){if(!a.provider||!a.hasApiKey&&!H[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}">${D(n.content)}</div>`).join(""),t=a.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${D(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}${t}</div>`}function A(){requestAnimationFrame(()=>{let e=u.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function $e(){let t=u.querySelector('[data-field="apiKey"]')?.value||"";if(!a.provider){a.saveStatus="error",C(),setTimeout(()=>{a.saveStatus="",x()},2e3);return}if(!I()){a.saveStatus="error",C();let n=u.querySelector('[data-action="save-settings"]');n&&(n.innerHTML="Not connected - check terminal"),setTimeout(()=>{a.saveStatus="",x()},3e3);return}let o={provider:a.provider,model:a.model};t&&(o.apiKey=t),a.saveStatus="saving",C();try{let n=await Promise.race([k("config.set",o),new Promise((s,i)=>setTimeout(()=>i(new Error("Save timed out")),8e3))]);a.hasApiKey=!!(t||a.hasApiKey),a.saveStatus="saved",C(),setTimeout(()=>{a.saveStatus="",a.activePanel==="settings"&&w("chat")},1200)}catch(n){a.saveStatus="error";let s=u.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="",x()},4e3)}}function C(){let e=u.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=`${c.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 ce(){let e=v.value.trim();if(!e||a.streaming)return;if(!a.provider||!a.hasApiKey&&!H[a.provider]?.local){w("settings");return}a.messages.push({role:"user",content:e}),a.streaming=!0,a.streamContent="",v.value="",w("chat");let t=te(a.selectedElement,a.screenshot);t.pageUrl=window.location.href,t.pageTitle=document.title;try{let o=await G("llm.chat",{provider:a.provider,model:a.model,messages:a.messages.map(n=>({role:n.role,content:n.content})),context:t},n=>{a.streamContent+=n;let s=u.querySelector(".om-msg-assistant:last-child");s&&(s.innerHTML=`<span class="om-spinner"></span>${D(a.streamContent)}`,A())});if(a.messages.push({role:"assistant",content:a.streamContent||o?.content||""}),o?.modifications?.length){for(let n of o.modifications)if(n.type==="edit"&&n.file&&n.search&&n.replace)try{let i=(await k("fs.read",{path:se(n.file)})).payload?.content;if(i?.includes(n.search)){let r=await k("fs.write",{path:se(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(o){a.messages.push({role:"system",content:`Error: ${o.message}`})}a.streaming=!1,a.streamContent="",x(),A()}function se(e){return a.roots.length>0?a.roots[0]+"/"+e:e}var S=null,L=null;function Pe(){a.selecting?de():Ne()}function Ne(){a.selecting=!0,document.body.style.cursor="crosshair",M(),L=e=>{let t=e.target;if(t.closest("openmagic-toolbar")||t.dataset?.openmagic)return;let o=t.getBoundingClientRect();j({x:o.x,y:o.y,width:o.width,height:o.height})},S=e=>{e.preventDefault(),e.stopPropagation();let t=e.target;t.closest("openmagic-toolbar")||t.dataset?.openmagic||(a.selectedElement=K(t),de(),$(),v.focus())},document.addEventListener("mousemove",L,!0),document.addEventListener("click",S,!0)}function de(){a.selecting=!1,document.body.style.cursor="",V(),L&&(document.removeEventListener("mousemove",L,!0),L=null),S&&(document.removeEventListener("click",S,!0),S=null),M()}async function _e(){let e=await F();e&&(a.screenshot=e,$(),v.focus())}function Oe(){let e=!1,t=0,o=0,n=0,s=0;h.addEventListener("mousedown",i=>{let r=i.target;if(r.closest("[data-action]")||!r.closest(".om-grab")&&!r.closest(".om-pill-brand"))return;e=!0,t=i.clientX,o=i.clientY;let l=h.getBoundingClientRect();n=l.left,s=l.top,i.preventDefault()}),document.addEventListener("mousemove",i=>{e&&(h.style.left=n+i.clientX-t+"px",h.style.top=s+i.clientY-o+"px",h.style.right="auto",h.style.bottom="auto")}),document.addEventListener("mouseup",()=>{e=!1})}function D(e){let t=document.createElement("div");return t.textContent=e,t.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 t=e.version.split(".").map(Number),o=ie.split(".").map(Number);for(let n=0;n<3;n++){if((t[n]||0)>(o[n]||0)){a.updateAvailable=!0,a.latestVersion=e.version,Ae();return}if((t[n]||0)<(o[n]||0))return}}).catch(()=>{})}function Ae(){if(g.querySelector(".om-update-dot"))return;let t=document.createElement("span");t.className="om-update-dot",t.title=`v${a.latestVersion} available`,t.addEventListener("click",()=>w("settings"));let o=g.querySelector(".om-toolbar-header");o&&o.appendChild(t)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",oe):oe());})();
346
+ </div>`}function Ne(){if(!a.provider||!a.hasApiKey&&!O[a.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=a.messages.map((n,s)=>{if(n.content.startsWith("__DIFF__")){let i=n.content.split("__"),r=i[3],l=atob(i[4]),c=atob(i[5]);return`<div class="om-diff-card" data-diff-idx="${s}">
347
+ <div class="om-diff-file">${x(r)}</div>
348
+ <div class="om-diff-removed">${x(l.slice(0,200))}</div>
349
+ <div class="om-diff-added">${x(c.slice(0,200))}</div>
350
+ <div class="om-diff-actions">
351
+ <button class="om-btn om-btn-sm" data-action="apply-diff" data-file="${x(r)}" data-search="${i[4]}" data-replace="${i[5]}">Apply</button>
352
+ <button class="om-btn-secondary om-btn-sm" data-action="reject-diff" data-idx="${s}">Reject</button>
353
+ </div>
354
+ </div>`}return`<div class="om-msg om-msg-${n.role}">${x(n.content)}</div>`}).join(""),t=a.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${x(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}${t}</div>`}function C(){requestAnimationFrame(()=>{let e=f.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function Oe(){let t=f.querySelector('[data-field="apiKey"]')?.value||"";if(!a.provider){a.saveStatus="error",N(),setTimeout(()=>{a.saveStatus="",y()},2e3);return}if(!J()){a.saveStatus="error",N();let n=f.querySelector('[data-action="save-settings"]');n&&(n.innerHTML="Not connected - check terminal"),setTimeout(()=>{a.saveStatus="",y()},3e3);return}let o={provider:a.provider,model:a.model};t&&(o.apiKey=t),a.saveStatus="saving",N();try{let n=await Promise.race([k("config.set",o),new Promise((s,i)=>setTimeout(()=>i(new Error("Save timed out")),8e3))]);a.hasApiKey=!!(t||a.hasApiKey),a.saveStatus="saved",N(),setTimeout(()=>{a.saveStatus="",a.activePanel==="settings"&&M("chat")},1200)}catch(n){a.saveStatus="error";let s=f.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="",y()},4e3)}}function N(){let e=f.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 he(){let e=S.value.trim();if(!e||a.streaming)return;if(!a.provider||!a.hasApiKey&&!O[a.provider]?.local){M("settings");return}a.messages.push({role:"user",content:e}),a.streaming=!0,a.streamContent="",S.value="",M("chat");let t=le(a.selectedElement,a.screenshot);t.pageUrl=window.location.href,t.pageTitle=document.title;try{let o=await k("fs.list",{});o?.payload?.projectTree&&(t.projectTree=o.payload.projectTree)}catch{}try{let o=await W("llm.chat",{provider:a.provider,model:a.model,messages:a.messages.map(n=>({role:n.role,content:n.content})),context:t},n=>{a.streamContent+=n;let s=f.querySelector(".om-msg-assistant:last-child");s&&(s.innerHTML=`<span class="om-spinner"></span>${x(a.streamContent)}`,C())});if(a.messages.push({role:"assistant",content:a.streamContent||o?.content||""}),o?.modifications?.length){for(let n of o.modifications)if(n.type==="edit"&&n.file&&n.search&&n.replace){let s=Math.random().toString(36).slice(2);a.messages.push({role:"system",content:`__DIFF__${s}__${n.file}__${btoa(n.search)}__${btoa(n.replace)}__`})}}}catch(o){a.messages.push({role:"system",content:`Error: ${o.message}`})}a.streaming=!1,a.streamContent="",y(),C()}var L=null,T=null;function Re(){a.selecting?j():D()}function D(){a.selecting=!0,document.body.style.cursor="crosshair",$(),T=t=>{let o=t.target;if(o.closest("openmagic-toolbar")||o.dataset?.openmagic)return;let n=o.getBoundingClientRect();Q({x:n.x,y:n.y,width:n.width,height:n.height})},L=t=>{t.preventDefault(),t.stopPropagation();let o=t.target;o.closest("openmagic-toolbar")||o.dataset?.openmagic||(a.selectedElement=Y(o),j(),R(),S.focus())};let e=t=>{t.key==="Escape"&&j()};document.addEventListener("mousemove",T,!0),document.addEventListener("click",L,!0),document.addEventListener("keydown",e,!0),D._escHandler=e}function j(){a.selecting=!1,document.body.style.cursor="",Z(),T&&(document.removeEventListener("mousemove",T,!0),T=null),L&&(document.removeEventListener("click",L,!0),L=null);let e=D._escHandler;e&&(document.removeEventListener("keydown",e,!0),D._escHandler=null),$()}async function De(){let e=a.selectedElement?document.querySelector(a.selectedElement.cssSelector):void 0,t=await ee(e||void 0);t&&(a.screenshot=t,R(),S.focus())}function Ae(){let e=!1,t=0,o=0,n=0,s=0;p.addEventListener("mousedown",i=>{let r=i.target;if(r.closest("[data-action]")||!r.closest(".om-grab")&&!r.closest(".om-pill-brand"))return;e=!0,t=i.clientX,o=i.clientY;let l=p.getBoundingClientRect();n=l.left,s=l.top,i.preventDefault()}),document.addEventListener("mousemove",i=>{e&&(p.style.left=n+i.clientX-t+"px",p.style.top=s+i.clientY-o+"px",p.style.right="auto",p.style.bottom="auto")}),document.addEventListener("mouseup",()=>{if(e){e=!1;try{localStorage.setItem("__om_pos__",JSON.stringify({left:p.style.left,top:p.style.top}))}catch{}}})}function x(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function qe(){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=me.split(".").map(Number);for(let n=0;n<3;n++){if((t[n]||0)>(o[n]||0)){a.updateAvailable=!0,a.latestVersion=e.version,Be();return}if((t[n]||0)<(o[n]||0))return}}).catch(()=>{})}function Be(){if(b.querySelector(".om-update-dot"))return;let t=document.createElement("span");t.className="om-update-dot",t.title=`v${a.latestVersion} available`,t.addEventListener("click",()=>M("settings"));let o=b.querySelector(".om-toolbar-header");o&&o.appendChild(t)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",ce):ce());})();
318
355
  //# sourceMappingURL=index.global.js.map