openmagic 0.31.1 → 0.31.2

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.
package/README.md CHANGED
@@ -25,17 +25,25 @@ No framework plugin. No IDE extension. No account. Bring your own API key.
25
25
 
26
26
  ---
27
27
 
28
+ <div align="center">
29
+
30
+ ![OpenMagic Demo](https://raw.githubusercontent.com/Kalmuraee/OpenMagic/main/docs/demo.gif)
31
+
32
+ </div>
33
+
34
+ ---
35
+
28
36
  ## Quick Start
29
37
 
30
38
  ```bash
31
39
  # 1. Start your dev server as usual
32
40
  npm run dev
33
41
 
34
- # 2. Launch OpenMagic (auto-detects your dev server)
42
+ # 2. In your project folder, run OpenMagic (auto-detects your dev server)
35
43
  npx openmagic@latest
36
44
  ```
37
45
 
38
- A proxied version of your app opens with the AI toolbar overlaid. That is it.
46
+ Run `npx openmagic@latest` from your project folder so it can find your source files and dev server. A proxied version of your app opens with the AI toolbar overlaid. That is it.
39
47
 
40
48
  ---
41
49
 
@@ -77,7 +85,7 @@ OpenMagic is a single-port reverse proxy. It sits between your browser and your
77
85
  +-----------------------+
78
86
  ```
79
87
 
80
- 1. **Proxy** -- All requests forward to your dev server. HTML responses get a `<script>` tag injected before `</body>`.
88
+ 1. **Proxy** -- All requests forward to your dev server. HTML responses get the toolbar `<script>` tag appended automatically.
81
89
  2. **Toolbar** -- A Shadow DOM Web Component. Fully isolated from your app's styles.
82
90
  3. **Server** -- Local Node.js process handling file I/O and proxying LLM calls. API keys never leave your machine.
83
91
  4. **HMR** -- When the AI modifies source files, your dev server's hot module replacement picks up changes automatically.
@@ -129,7 +137,7 @@ Stop with `Ctrl+C`. No files modified. No dependencies added. No traces.
129
137
  | `-p, --port <port>` | Dev server port to proxy | Auto-detect |
130
138
  | `-l, --listen <port>` | OpenMagic proxy port | `4567` |
131
139
  | `-r, --root <paths...>` | Project root directories | Current directory |
132
- | `--host <host>` | Dev server host | `127.0.0.1` |
140
+ | `--host <host>` | Dev server host | `localhost` |
133
141
  | `--no-open` | Do not auto-open browser | `false` |
134
142
 
135
143
  ### Multi-Repo Support
@@ -145,7 +153,7 @@ Settings persist in `~/.openmagic/config.json` (your home directory, never in yo
145
153
  ```json
146
154
  {
147
155
  "provider": "anthropic",
148
- "model": "claude-opus-4-6-20260326",
156
+ "model": "claude-opus-4-6",
149
157
  "apiKey": "sk-ant-..."
150
158
  }
151
159
  ```
@@ -162,7 +170,7 @@ npx openmagic --port 3000
162
170
 
163
171
  ## Security
164
172
 
165
- - **Localhost only** -- The proxy and WebSocket bind to `127.0.0.1`. Not accessible from the network.
173
+ - **Localhost only** -- The proxy and WebSocket bind to `localhost`. Not accessible from the network.
166
174
  - **Session tokens** -- Each session generates a random token. The toolbar authenticates before accessing any API.
167
175
  - **Path sandboxing** -- File operations are restricted to configured root directories. Symlinks that escape the root are rejected.
168
176
  - **API keys stay local** -- Keys live in `~/.openmagic/config.json`. They are proxied through the local server, never exposed to the browser or any third party.
@@ -245,7 +253,7 @@ See the repo for project structure and contribution guidelines.
245
253
 
246
254
  ## License
247
255
 
248
- MIT -- Copyright (c) 2025-2026 Khalid Almuraee. See [LICENSE](./LICENSE) for details.
256
+ MIT -- Copyright (c) 2026 Khalid Almuraee. See [LICENSE](./LICENSE) for details.
249
257
 
250
258
  ---
251
259
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var OpenMagicToolbar=(()=>{var $e=`
2
+ "use strict";var OpenMagicToolbar=(()=>{var Me=`
3
3
  :host {
4
4
  all: initial;
5
5
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
@@ -81,6 +81,8 @@
81
81
  .om-pill-btn:hover { background: rgba(108, 92, 231, 0.15); color: #a29bfe; }
82
82
  .om-pill-btn:focus-visible { outline: 2px solid #6c5ce7; outline-offset: 2px; }
83
83
  .om-pill-btn.active { background: rgba(108, 92, 231, 0.25); color: #c4b5fd; }
84
+ .om-pill-btn-bug { color: #888; opacity: 0.7; padding: 5px 4px; }
85
+ .om-pill-btn-bug:hover { opacity: 1; color: #e94560; background: rgba(233, 69, 96, 0.1); }
84
86
 
85
87
  .om-status-dot {
86
88
  width: 7px; height: 7px; border-radius: 50%; margin-left: auto; flex-shrink: 0;
@@ -372,28 +374,29 @@
372
374
  .om-msg:hover .om-copy-btn { opacity: 1; }
373
375
  .om-copy-btn:hover { color: #ccc; background: rgba(0,0,0,0.5); }
374
376
  .om-msg { position: relative; }
375
- `;var _=null,C=new Map,G=[],me=[],B=!1,Le=!1,de=null,pe=0;function ue(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function ge(e,t){return Le=!0,new Promise((s,n)=>{let a=!1,i=setTimeout(()=>{a||(a=!0,n(new Error("Handshake timeout")),_?.close())},1e4);try{let r=window.location.hostname||"127.0.0.1",d=window.location.protocol==="https:"?"wss:":"ws:";_=new WebSocket(`${d}//${r}:${e}/__openmagic__/ws`),_.onopen=()=>{let l=ue();_.send(JSON.stringify({id:l,type:"handshake",payload:{token:t}})),C.set(l,p=>{if(p.type==="handshake.ok"){clearTimeout(i),B=!0,pe=0;for(let c of me)_?.send(c);me=[],a||(a=!0,s())}else p.type==="error"&&(clearTimeout(i),a||(a=!0,n(new Error(p.payload?.message||"Handshake failed"))))})},_.onmessage=l=>{try{let p=JSON.parse(l.data);p.id&&C.has(p.id)&&(C.get(p.id)(p),(p.type==="llm.done"||p.type==="llm.error"||!p.type.startsWith("llm."))&&C.delete(p.id));for(let c of G)c(p)}catch{}},_.onclose=()=>{let l=B;if(B=!1,C.forEach((p,c)=>{p({type:"error",id:c,payload:{message:"Connection lost"}})}),C.clear(),!l&&!a){clearTimeout(i),a=!0,n(new Error("WebSocket closed before handshake"));return}if(l&&Le&&!de){let p=Math.min(2e3*Math.pow(1.5,pe),3e4);pe++,de=setTimeout(()=>{de=null,ge(e,t).then(()=>{for(let c of G)c({type:"reconnected",payload:{}})}).catch(()=>{})},p)}},_.onerror=()=>{!B&&!a&&(clearTimeout(i),a=!0,n(new Error("WebSocket connection failed")))}}catch(r){clearTimeout(i),a||(a=!0,n(r))}})}function Me(e){let t=JSON.stringify(e);_&&_.readyState===WebSocket.OPEN&&B?_.send(t):me.push(t)}function E(e,t){return new Promise((s,n)=>{let a=ue(),i=setTimeout(()=>{C.delete(a),n(new Error("Request timeout"))},3e4);C.set(a,r=>{clearTimeout(i),r.type==="error"?n(new Error(r.payload?.message||"Unknown error")):s(r)}),Me({id:a,type:e,payload:t})})}function Te(e,t,s){return new Promise((n,a)=>{let i=ue(),r=setTimeout(()=>{C.delete(i),a(new Error("Stream timeout"))},12e4);C.set(i,d=>{d.type==="llm.chunk"?s(d.payload?.delta||""):d.type==="llm.done"?(clearTimeout(r),C.delete(i),n(d.payload)):(d.type==="llm.error"||d.type==="error")&&(clearTimeout(r),C.delete(i),a(new Error(d.payload?.message||"Stream error")))}),Me({id:i,type:e,payload:t})})}function Ce(e){return G.push(e),()=>{G=G.filter(t=>t!==e)}}function He(){return B}var Pe=["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 _e(e){let t=window.getComputedStyle(e),s={};for(let c of Pe)s[c]=t.getPropertyValue(c);let n=e.getBoundingClientRect(),a={};if(e.parentElement&&e.parentElement!==document.body){let c=window.getComputedStyle(e.parentElement);for(let f of Pe)a[f]=c.getPropertyValue(f)}let i=[];if(e.parentElement){let c=Array.from(e.parentElement.children),f=c.indexOf(e),m=Math.max(0,f-3),b=Math.min(c.length,f+4);m>0&&i.push(`... ${m} elements before ...`);for(let u=m;u<b;u++){let y=c[u],h=y.tagName.toLowerCase(),S=(y.className||"").toString().slice(0,60);y===e?i.push(`[SELECTED] <${h} class="${S}">`):i.push(`<${h} class="${S}">`)}b<c.length&&i.push(`... ${c.length-b} elements after ...`)}let r=st(e),d={};for(let c of Array.from(e.attributes))(c.name.startsWith("aria-")||c.name==="role"||c.name==="tabindex")&&(d[c.name]=c.value);let l=[];for(let c of Array.from(e.attributes))c.name.startsWith("on")&&l.push(c.name);let p=at(e);return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().slice(0,200),outerHTML:tt(e),cssSelector:nt(e),xpath:ot(e),computedStyles:s,ancestry:Qe(e),componentHint:et(e),rect:{x:n.x,y:n.y,width:n.width,height:n.height},parentStyles:a,siblings:i,matchedCssRules:r,viewport:{width:window.innerWidth,height:window.innerHeight},ariaAttributes:d,eventHandlers:l,reactProps:p}}function Qe(e,t=5){let s=[],n=e.parentElement;for(;n&&n!==document.body&&s.length<t;){let a=n.tagName.toLowerCase(),i=(typeof n.className=="string"?n.className:"").split(/\s+/).filter(r=>r.length>1&&!r.startsWith("_")).slice(0,3).join(".");s.push(i?`${a}.${i}`:a),n=n.parentElement}return s}function et(e){let t=e;for(;t&&t!==document.body;){let s=t.getAttribute("data-component")||t.getAttribute("data-testid")||t.getAttribute("data-cy");if(s)return s;let n=Object.keys(t);for(let a of n)if(a.startsWith("__reactFiber")||a.startsWith("__reactInternalInstance"))try{let i=t[a],r=i?.type?.name||i?.type?.displayName||i?.return?.type?.name||i?.return?.type?.displayName;if(r&&r!=="div"&&r!=="span"&&r.length>1)return r}catch{}t=t.parentElement}return""}function tt(e){let t=e.cloneNode(!0);t.querySelectorAll("script, style, svg").forEach(a=>a.remove());let n=t.outerHTML;if(n.length>2e3){let a=e.tagName.toLowerCase(),i=Array.from(e.attributes).map(d=>`${d.name}="${d.value}"`).join(" "),r=Array.from(e.children).slice(0,5).map(d=>`<${d.tagName.toLowerCase()} .../>`).join(`
376
- `);n=`<${a} ${i}>
377
- ${r}
377
+ `;var _=null,C=new Map,K=[],he=[],j=!1,Le=!1,me=null,ue=0;function ge(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function fe(e,t){return Le=!0,new Promise((s,o)=>{let r=!1,i=setTimeout(()=>{r||(r=!0,o(new Error("Handshake timeout")),_?.close())},1e4);try{let a=window.location.hostname||"127.0.0.1",c=window.location.protocol==="https:"?"wss:":"ws:";_=new WebSocket(`${c}//${a}:${e}/__openmagic__/ws`),_.onopen=()=>{let l=ge();_.send(JSON.stringify({id:l,type:"handshake",payload:{token:t}})),C.set(l,p=>{if(p.type==="handshake.ok"){clearTimeout(i),j=!0,ue=0;for(let d of he)_?.send(d);he=[],r||(r=!0,s())}else p.type==="error"&&(clearTimeout(i),r||(r=!0,o(new Error(p.payload?.message||"Handshake failed"))))})},_.onmessage=l=>{try{let p=JSON.parse(l.data);p.id&&C.has(p.id)&&(C.get(p.id)(p),(p.type==="llm.done"||p.type==="llm.error"||!p.type.startsWith("llm."))&&C.delete(p.id));for(let d of K)d(p)}catch{}},_.onclose=()=>{let l=j;if(j=!1,C.forEach((p,d)=>{p({type:"error",id:d,payload:{message:"Connection lost"}})}),C.clear(),!l&&!r){clearTimeout(i),r=!0,o(new Error("WebSocket closed before handshake"));return}if(l&&Le&&!me){let p=Math.min(2e3*Math.pow(1.5,ue),3e4);ue++,me=setTimeout(()=>{me=null,fe(e,t).then(()=>{for(let d of K)d({type:"reconnected",payload:{}})}).catch(()=>{})},p)}},_.onerror=()=>{!j&&!r&&(clearTimeout(i),r=!0,o(new Error("WebSocket connection failed")))}}catch(a){clearTimeout(i),r||(r=!0,o(a))}})}function Te(e){let t=JSON.stringify(e);_&&_.readyState===WebSocket.OPEN&&j?_.send(t):he.push(t)}function $(e,t){return new Promise((s,o)=>{let r=ge(),i=setTimeout(()=>{C.delete(r),o(new Error("Request timeout"))},3e4);C.set(r,a=>{clearTimeout(i),a.type==="error"?o(new Error(a.payload?.message||"Unknown error")):s(a)}),Te({id:r,type:e,payload:t})})}function Ce(e,t,s){return new Promise((o,r)=>{let i=ge(),a=setTimeout(()=>{C.delete(i),r(new Error("Stream timeout"))},12e4);C.set(i,c=>{c.type==="llm.chunk"?s(c.payload?.delta||""):c.type==="llm.done"?(clearTimeout(a),C.delete(i),o(c.payload)):(c.type==="llm.error"||c.type==="error")&&(clearTimeout(a),C.delete(i),r(new Error(c.payload?.message||"Stream error")))}),Te({id:i,type:e,payload:t})})}function He(e){return K.push(e),()=>{K=K.filter(t=>t!==e)}}function Pe(){return j}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 Ne(e){let t=window.getComputedStyle(e),s={};for(let d of _e)s[d]=t.getPropertyValue(d);let o=e.getBoundingClientRect(),r={};if(e.parentElement&&e.parentElement!==document.body){let d=window.getComputedStyle(e.parentElement);for(let f of _e)r[f]=d.getPropertyValue(f)}let i=[];if(e.parentElement){let d=Array.from(e.parentElement.children),f=d.indexOf(e),m=Math.max(0,f-3),b=Math.min(d.length,f+4);m>0&&i.push(`... ${m} elements before ...`);for(let u=m;u<b;u++){let y=d[u],g=y.tagName.toLowerCase(),S=(y.className||"").toString().slice(0,60);y===e?i.push(`[SELECTED] <${g} class="${S}">`):i.push(`<${g} class="${S}">`)}b<d.length&&i.push(`... ${d.length-b} elements after ...`)}let a=at(e),c={};for(let d of Array.from(e.attributes))(d.name.startsWith("aria-")||d.name==="role"||d.name==="tabindex")&&(c[d.name]=d.value);let l=[];for(let d of Array.from(e.attributes))d.name.startsWith("on")&&l.push(d.name);let p=rt(e);return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().slice(0,200),outerHTML:nt(e),cssSelector:ot(e),xpath:st(e),computedStyles:s,ancestry:et(e),componentHint:tt(e),rect:{x:o.x,y:o.y,width:o.width,height:o.height},parentStyles:r,siblings:i,matchedCssRules:a,viewport:{width:window.innerWidth,height:window.innerHeight},ariaAttributes:c,eventHandlers:l,reactProps:p}}function et(e,t=5){let s=[],o=e.parentElement;for(;o&&o!==document.body&&s.length<t;){let r=o.tagName.toLowerCase(),i=(typeof o.className=="string"?o.className:"").split(/\s+/).filter(a=>a.length>1&&!a.startsWith("_")).slice(0,3).join(".");s.push(i?`${r}.${i}`:r),o=o.parentElement}return s}function tt(e){let t=e;for(;t&&t!==document.body;){let s=t.getAttribute("data-component")||t.getAttribute("data-testid")||t.getAttribute("data-cy");if(s)return s;let o=Object.keys(t);for(let r of o)if(r.startsWith("__reactFiber")||r.startsWith("__reactInternalInstance"))try{let i=t[r],a=i?.type?.name||i?.type?.displayName||i?.return?.type?.name||i?.return?.type?.displayName;if(a&&a!=="div"&&a!=="span"&&a.length>1)return a}catch{}t=t.parentElement}return""}function nt(e){let t=e.cloneNode(!0);t.querySelectorAll("script, style, svg").forEach(r=>r.remove());let o=t.outerHTML;if(o.length>2e3){let r=e.tagName.toLowerCase(),i=Array.from(e.attributes).map(c=>`${c.name}="${c.value}"`).join(" "),a=Array.from(e.children).slice(0,5).map(c=>`<${c.tagName.toLowerCase()} .../>`).join(`
378
+ `);o=`<${r} ${i}>
379
+ ${a}
378
380
  ${e.children.length>5?`<!-- +${e.children.length-5} more children -->`:""}
379
- </${a}>`}return n}function nt(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=[],s=e;for(;s&&s!==document.body;){let n=s.tagName.toLowerCase();if(s.id){t.unshift(`#${CSS.escape(s.id)}`);break}if(s.className&&typeof s.className=="string"){let i=s.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 a=s.parentElement;if(a){let i=Array.from(a.children).filter(r=>r.tagName===s.tagName);if(i.length>1){let r=i.indexOf(s)+1;n+=`:nth-of-type(${r})`}}t.unshift(n),s=s.parentElement}return t.join(" > ")}function ot(e){let t=[],s=e;for(;s&&s!==document;){if(s.nodeType===Node.ELEMENT_NODE){let n=s,a=1,i=n.previousElementSibling;for(;i;)i.tagName===n.tagName&&a++,i=i.previousElementSibling;t.unshift(`${n.tagName.toLowerCase()}[${a}]`)}s=s.parentNode}return"/"+t.join("/")}function st(e){let t=[];try{for(let s of Array.from(document.styleSheets))try{let n=s.cssRules||s.rules;if(!n)continue;for(let a of Array.from(n))if(a instanceof CSSStyleRule)try{if(e.matches(a.selectorText)){let i=a.cssText;i.length>10&&i.length<500&&t.push(i)}}catch{}}catch{}}catch{}return t.slice(0,15)}function at(e){try{let t=Object.keys(e);for(let s of t)if(s.startsWith("__reactFiber")||s.startsWith("__reactInternalInstance")){let n=e[s];if(!n?.memoizedProps)continue;let a=n.memoizedProps,i={},r=0;for(let[d,l]of Object.entries(a)){if(r>=10)break;if(d==="children")continue;let p=typeof l;p==="string"||p==="number"||p==="boolean"||l===null?(i[d]=l,r++):p==="function"?(i[d]="[function]",r++):Array.isArray(l)&&(i[d]=`[Array(${l.length})]`,r++)}return Object.keys(i).length>0?i:null}}catch{}return null}var H=null;function Ne(e){H||(H=document.createElement("div"),H.style.cssText=`
381
+ </${r}>`}return o}function ot(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=[],s=e;for(;s&&s!==document.body;){let o=s.tagName.toLowerCase();if(s.id){t.unshift(`#${CSS.escape(s.id)}`);break}if(s.className&&typeof s.className=="string"){let i=s.className.trim().split(/\s+/).filter(a=>!a.startsWith("__")&&a.length<30).slice(0,2).map(a=>CSS.escape(a));i.length>0&&(o+="."+i.join("."))}let r=s.parentElement;if(r){let i=Array.from(r.children).filter(a=>a.tagName===s.tagName);if(i.length>1){let a=i.indexOf(s)+1;o+=`:nth-of-type(${a})`}}t.unshift(o),s=s.parentElement}return t.join(" > ")}function st(e){let t=[],s=e;for(;s&&s!==document;){if(s.nodeType===Node.ELEMENT_NODE){let o=s,r=1,i=o.previousElementSibling;for(;i;)i.tagName===o.tagName&&r++,i=i.previousElementSibling;t.unshift(`${o.tagName.toLowerCase()}[${r}]`)}s=s.parentNode}return"/"+t.join("/")}function at(e){let t=[];try{for(let s of Array.from(document.styleSheets))try{let o=s.cssRules||s.rules;if(!o)continue;for(let r of Array.from(o))if(r instanceof CSSStyleRule)try{if(e.matches(r.selectorText)){let i=r.cssText;i.length>10&&i.length<500&&t.push(i)}}catch{}}catch{}}catch{}return t.slice(0,15)}function rt(e){try{let t=Object.keys(e);for(let s of t)if(s.startsWith("__reactFiber")||s.startsWith("__reactInternalInstance")){let o=e[s];if(!o?.memoizedProps)continue;let r=o.memoizedProps,i={},a=0;for(let[c,l]of Object.entries(r)){if(a>=10)break;if(c==="children")continue;let p=typeof l;p==="string"||p==="number"||p==="boolean"||l===null?(i[c]=l,a++):p==="function"?(i[c]="[function]",a++):Array.isArray(l)&&(i[c]=`[Array(${l.length})]`,a++)}return Object.keys(i).length>0?i:null}}catch{}return null}var H=null;function Re(e){H||(H=document.createElement("div"),H.style.cssText=`
380
382
  position: fixed;
381
383
  pointer-events: none;
382
384
  z-index: 2147483646;
383
385
  border: 2px solid #6c5ce7;
384
386
  background: rgba(108, 92, 231, 0.1);
385
387
  transition: all 0.1s ease;
386
- `,H.dataset.openmagic="highlight",document.body.appendChild(H)),H.style.left=`${e.x}px`,H.style.top=`${e.y}px`,H.style.width=`${e.width}px`,H.style.height=`${e.height}px`,H.style.display="block"}function Re(){H&&(H.style.display="none")}async function Ae(e){try{let t=e||document.body,s=await rt(t);if(s)return{data:s}}catch{}try{let t=await it(e);if(t)return{data:t}}catch(t){return{data:null,error:`Screenshot failed: ${t.message||"unknown error"}. Try using the image attachment button instead.`}}return{data:null,error:"Screenshot capture not available on this page. Try pasting or dragging an image instead."}}async function rt(e){let t=e.getBoundingClientRect(),s=Math.min(t.width||window.innerWidth,1920),n=Math.min(t.height||window.innerHeight,1080),a=Oe(e,0,4);if(!a)return null;let i=`
387
- <svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${n}">
388
+ `,H.dataset.openmagic="highlight",document.body.appendChild(H)),H.style.left=`${e.x}px`,H.style.top=`${e.y}px`,H.style.width=`${e.width}px`,H.style.height=`${e.height}px`,H.style.display="block"}function Ae(){H&&(H.style.display="none")}async function Oe(e){try{let t=e||document.body,s=await it(t);if(s)return{data:s}}catch{}try{let t=await lt(e);if(t)return{data:t}}catch(t){return{data:null,error:`Screenshot failed: ${t.message||"unknown error"}. Try using the image attachment button instead.`}}return{data:null,error:"Screenshot capture not available on this page. Try pasting or dragging an image instead."}}async function it(e){let t=e.getBoundingClientRect(),s=Math.min(t.width||window.innerWidth,1920),o=Math.min(t.height||window.innerHeight,1080),r=qe(e,0,4);if(!r)return null;let i=`
389
+ <svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${o}">
388
390
  <foreignObject width="100%" height="100%">
389
- <div xmlns="http://www.w3.org/1999/xhtml" style="width:${s}px;height:${n}px;overflow:hidden;">
390
- ${a.outerHTML}
391
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width:${s}px;height:${o}px;overflow:hidden;">
392
+ ${r.outerHTML}
391
393
  </div>
392
394
  </foreignObject>
393
- </svg>`,r=new Blob([i],{type:"image/svg+xml;charset=utf-8"}),d=URL.createObjectURL(r);return new Promise(l=>{let p=new Image,c=document.createElement("canvas"),f=Math.min(window.devicePixelRatio||1,2);c.width=s*f,c.height=n*f,p.onload=()=>{URL.revokeObjectURL(d);let m=c.getContext("2d");if(!m){l(null);return}m.scale(f,f),m.drawImage(p,0,0);try{l(c.toDataURL("image/png",.8))}catch{l(null)}},p.onerror=()=>{URL.revokeObjectURL(d),l(null)},setTimeout(()=>{URL.revokeObjectURL(d),l(null)},5e3),p.src=d})}async function it(e){let t=e||document.documentElement,s=t.getBoundingClientRect(),n=document.createElement("canvas");n.width=400,n.height=300;let a=n.getContext("2d");return a?(a.fillStyle="#1a1a2e",a.fillRect(0,0,400,300),a.fillStyle="#e0e0e0",a.font="14px system-ui",a.fillText(`Element: <${t.tagName.toLowerCase()}>`,20,30),a.fillStyle="#888",a.font="12px system-ui",a.fillText(`Size: ${Math.round(s.width)}x${Math.round(s.height)}`,20,55),a.fillText(`Classes: ${(t.className||"").toString().slice(0,40)}`,20,75),a.fillText(`Page: ${window.location.pathname}`,20,95),a.fillStyle="#6c5ce7",a.font="11px system-ui",a.fillText("(Full screenshot unavailable \u2014 context sent as metadata)",20,130),n.toDataURL("image/png")):null}function Oe(e,t,s){if(t>s)return null;try{let n=e.cloneNode(!1);if(n.tagName==="SCRIPT"||n.tagName==="STYLE"||n.tagName==="SVG"||n.tagName==="CANVAS"||n.tagName==="VIDEO"||n.tagName==="IFRAME")return null;let a=window.getComputedStyle(e),i=["display","position","width","height","margin","padding","color","background-color","background","font-size","font-weight","font-family","border","border-radius","flex-direction","justify-content","align-items","gap","grid-template-columns","text-align","overflow"],r="";for(let d of i){let l=a.getPropertyValue(d);l&&l!=="normal"&&l!=="none"&&l!=="auto"&&l!=="0px"&&(r+=`${d}:${l};`)}n.setAttribute("style",r);for(let d=0;d<e.children.length&&d<20;d++){let l=Oe(e.children[d],t+1,s);l&&n.appendChild(l)}return n}catch{return null}}var Q=[];var qe=!1;function De(){if(qe)return;qe=!0;let e=window.fetch;window.fetch=async function(...n){let a=new Request(...n),i={method:a.method,url:a.url,timestamp:Date.now()};try{let r=await e.apply(this,n);return i.status=r.status,i.duration=Date.now()-i.timestamp,he(i),r}catch(r){throw i.status=0,i.duration=Date.now()-i.timestamp,he(i),r}};let t=XMLHttpRequest.prototype.open,s=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,a,...i){return this.__om_method=n,this.__om_url=a,this.__om_start=Date.now(),t.apply(this,[n,a,...i])},XMLHttpRequest.prototype.send=function(...n){return this.addEventListener("loadend",()=>{he({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()})}),s.apply(this,n)}}function he(e){e.url.includes("__openmagic__")||(Q.push(e),Q.length>50&&Q.shift())}function fe(){return[...Q]}var ee=[],lt=100,ze=!1;function Ie(){if(ze)return;ze=!0;let e=["log","warn","error","info","debug"];for(let t of e){let s=console[t];console[t]=function(...n){ee.push({level:t,args:n.map(a=>{try{return typeof a=="object"?JSON.stringify(a).slice(0,500):String(a)}catch{return String(a)}}),timestamp:Date.now()}),ee.length>lt&&ee.shift(),s.apply(console,n)}}}function ye(){return[...ee]}function Be(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:fe().map(s=>({method:s.method,url:s.url,status:s.status,duration:s.duration,timestamp:s.timestamp})),consoleLogs:ye().map(s=>({level:s.level,args:s.args,timestamp:s.timestamp}))}}var x={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>',copy:'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></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>',trash:'<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',minus:'<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="5" y1="12" x2="19" y2="12"/></svg>'},j={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 ne(e){let t=new TextEncoder().encode(e),s="";for(let n=0;n<t.length;n+=32768)s+=String.fromCharCode(...t.subarray(n,n+32768));return btoa(s)}function oe(e){let t=atob(e),s=new Uint8Array(t.length);for(let n=0;n<t.length;n++)s[n]=t.charCodeAt(n);return new TextDecoder().decode(s)}var Ge="0.31.1",o={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:[],groundedFiles:[],minimized:!1},w,$,z,We,Se,R;function ct(){try{sessionStorage.setItem("__om_state__",JSON.stringify({messages:o.messages,provider:o.provider,model:o.model,panelOpen:o.panelOpen,activePanel:o.activePanel}))}catch{}}function dt(){try{let e=JSON.parse(sessionStorage.getItem("__om_state__")||"{}");e.messages?.length&&(o.messages=e.messages),e.provider&&(o.provider=e.provider),e.model&&(o.model=e.model),e.panelOpen&&(o.panelOpen=e.panelOpen,o.activePanel=e.activePanel||"")}catch{}}function je(){if(document.querySelector("openmagic-toolbar"))return;dt();let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",w=e.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=$e,w.appendChild(t);let s=document.createElement("div");w.appendChild(s),s.innerHTML=pt(),$=s.querySelector(".om-toolbar"),z=s.querySelector(".om-prompt-input"),We=s.querySelector(".om-prompt-context"),Se=s.querySelector(".om-panel"),R=s.querySelector(".om-panel-body"),document.body.appendChild(e),mt(s),Et();try{let r=JSON.parse(localStorage.getItem("__om_pos__")||"");r?.left&&r?.top&&($.style.left=r.left,$.style.top=r.top,$.style.right="auto",$.style.bottom="auto")}catch{}De(),Ie(),Lt();let a=document.querySelector("script[data-openmagic-token]")?.dataset.openmagicToken||window.__OPENMAGIC_TOKEN__,i=parseInt(window.location.port,10)||(window.location.protocol==="https:"?443:80);a&&ge(i,a).then(()=>(o.connected=!0,ve(),E("config.get"))).then(r=>{let d=r.payload?.provider||"",l=r.payload?.model||"";o.provider=o.provider||d,o.model=o.model||l,o.configuredProviders=r.payload?.apiKeys||{},o.hasApiKey=o.configuredProviders[o.provider]||!1,o.roots=r.payload?.roots||[],o.panelOpen&&o.activePanel?O(o.activePanel):(!o.provider||!o.hasApiKey&&!Object.values(o.configuredProviders).some(Boolean))&&O("settings"),J()}).catch(()=>{o.connected=!1,ve()})}function pt(){return`
395
+ </svg>`,a=new Blob([i],{type:"image/svg+xml;charset=utf-8"}),c=URL.createObjectURL(a);return new Promise(l=>{let p=new Image,d=document.createElement("canvas"),f=Math.min(window.devicePixelRatio||1,2);d.width=s*f,d.height=o*f,p.onload=()=>{URL.revokeObjectURL(c);let m=d.getContext("2d");if(!m){l(null);return}m.scale(f,f),m.drawImage(p,0,0);try{l(d.toDataURL("image/png",.8))}catch{l(null)}},p.onerror=()=>{URL.revokeObjectURL(c),l(null)},setTimeout(()=>{URL.revokeObjectURL(c),l(null)},5e3),p.src=c})}async function lt(e){let t=e||document.documentElement,s=t.getBoundingClientRect(),o=document.createElement("canvas");o.width=400,o.height=300;let r=o.getContext("2d");return r?(r.fillStyle="#1a1a2e",r.fillRect(0,0,400,300),r.fillStyle="#e0e0e0",r.font="14px system-ui",r.fillText(`Element: <${t.tagName.toLowerCase()}>`,20,30),r.fillStyle="#888",r.font="12px system-ui",r.fillText(`Size: ${Math.round(s.width)}x${Math.round(s.height)}`,20,55),r.fillText(`Classes: ${(t.className||"").toString().slice(0,40)}`,20,75),r.fillText(`Page: ${window.location.pathname}`,20,95),r.fillStyle="#6c5ce7",r.font="11px system-ui",r.fillText("(Full screenshot unavailable \u2014 context sent as metadata)",20,130),o.toDataURL("image/png")):null}function qe(e,t,s){if(t>s)return null;try{let o=e.cloneNode(!1);if(o.tagName==="SCRIPT"||o.tagName==="STYLE"||o.tagName==="SVG"||o.tagName==="CANVAS"||o.tagName==="VIDEO"||o.tagName==="IFRAME")return null;let r=window.getComputedStyle(e),i=["display","position","width","height","margin","padding","color","background-color","background","font-size","font-weight","font-family","border","border-radius","flex-direction","justify-content","align-items","gap","grid-template-columns","text-align","overflow"],a="";for(let c of i){let l=r.getPropertyValue(c);l&&l!=="normal"&&l!=="none"&&l!=="auto"&&l!=="0px"&&(a+=`${c}:${l};`)}o.setAttribute("style",a);for(let c=0;c<e.children.length&&c<20;c++){let l=qe(e.children[c],t+1,s);l&&o.appendChild(l)}return o}catch{return null}}var Q=[];var ze=!1;function Ie(){if(ze)return;ze=!0;let e=window.fetch;window.fetch=async function(...o){let r=new Request(...o),i={method:r.method,url:r.url,timestamp:Date.now()};try{let a=await e.apply(this,o);return i.status=a.status,i.duration=Date.now()-i.timestamp,ye(i),a}catch(a){throw i.status=0,i.duration=Date.now()-i.timestamp,ye(i),a}};let t=XMLHttpRequest.prototype.open,s=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(o,r,...i){return this.__om_method=o,this.__om_url=r,this.__om_start=Date.now(),t.apply(this,[o,r,...i])},XMLHttpRequest.prototype.send=function(...o){return this.addEventListener("loadend",()=>{ye({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()})}),s.apply(this,o)}}function ye(e){e.url.includes("__openmagic__")||(Q.push(e),Q.length>50&&Q.shift())}function te(){return[...Q]}var ee=[],ct=100,De=!1;function Be(){if(De)return;De=!0;let e=["log","warn","error","info","debug"];for(let t of e){let s=console[t];console[t]=function(...o){ee.push({level:t,args:o.map(r=>{try{return typeof r=="object"?JSON.stringify(r).slice(0,500):String(r)}catch{return String(r)}}),timestamp:Date.now()}),ee.length>ct&&ee.shift(),s.apply(console,o)}}}function ne(){return[...ee]}function je(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:te().map(s=>({method:s.method,url:s.url,status:s.status,duration:s.duration,timestamp:s.timestamp})),consoleLogs:ne().map(s=>({level:s.level,args:s.args,timestamp:s.timestamp}))}}var x={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>',copy:'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></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>',bug:'<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m8 2 1.88 1.88M14.12 3.88 16 2M9 7.13v-1a3.003 3.003 0 1 1 6 0v1"/><path d="M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6"/><path d="M12 20v-9"/><path d="M6.53 9C4.6 8.8 3 7.1 3 5"/><path d="M6 13H2"/><path d="M3 21c0-2.1 1.7-3.9 3.8-4"/><path d="M20.97 5c0 2.1-1.6 3.8-3.5 4"/><path d="M22 13h-4"/><path d="M17.2 17c2.1.1 3.8 1.9 3.8 4"/></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>',trash:'<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',minus:'<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="5" y1="12" x2="19" y2="12"/></svg>'},B={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 se(e){let t=new TextEncoder().encode(e),s="";for(let o=0;o<t.length;o+=32768)s+=String.fromCharCode(...t.subarray(o,o+32768));return btoa(s)}function ae(e){let t=atob(e),s=new Uint8Array(t.length);for(let o=0;o<t.length;o++)s[o]=t.charCodeAt(o);return new TextDecoder().decode(s)}var Se="0.31.2",n={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:[],groundedFiles:[],minimized:!1},w,E,z,Ve,$e,R;function dt(){try{sessionStorage.setItem("__om_state__",JSON.stringify({messages:n.messages,provider:n.provider,model:n.model,panelOpen:n.panelOpen,activePanel:n.activePanel}))}catch{}}function pt(){try{let e=JSON.parse(sessionStorage.getItem("__om_state__")||"{}");e.messages?.length&&(n.messages=e.messages),e.provider&&(n.provider=e.provider),e.model&&(n.model=e.model),e.panelOpen&&(n.panelOpen=e.panelOpen,n.activePanel=e.activePanel||"")}catch{}}function Fe(){if(document.querySelector("openmagic-toolbar"))return;pt();let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",w=e.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=Me,w.appendChild(t);let s=document.createElement("div");w.appendChild(s),s.innerHTML=mt(),E=s.querySelector(".om-toolbar"),z=s.querySelector(".om-prompt-input"),Ve=s.querySelector(".om-prompt-context"),$e=s.querySelector(".om-panel"),R=s.querySelector(".om-panel-body"),document.body.appendChild(e),ut(s),Et();try{let a=JSON.parse(localStorage.getItem("__om_pos__")||"");a?.left&&a?.top&&(E.style.left=a.left,E.style.top=a.top,E.style.right="auto",E.style.bottom="auto")}catch{}Ie(),Be(),Lt();let r=document.querySelector("script[data-openmagic-token]")?.dataset.openmagicToken||window.__OPENMAGIC_TOKEN__,i=parseInt(window.location.port,10)||(window.location.protocol==="https:"?443:80);r&&fe(i,r).then(()=>(n.connected=!0,ve(),$("config.get"))).then(a=>{let c=a.payload?.provider||"",l=a.payload?.model||"";n.provider=n.provider||c,n.model=n.model||l,n.configuredProviders=a.payload?.apiKeys||{},n.hasApiKey=n.configuredProviders[n.provider]||!1,n.roots=a.payload?.roots||[],n.panelOpen&&n.activePanel?O(n.activePanel):(!n.provider||!n.hasApiKey&&!Object.values(n.configuredProviders).some(Boolean))&&O("settings"),J()}).catch(()=>{n.connected=!1,ve()})}function mt(){return`
394
396
  <div class="om-toolbar">
395
397
  <div class="om-toolbar-header">
396
398
  <span class="om-grab">${x.grip}</span>
399
+ <button class="om-pill-btn om-pill-btn-bug" data-action="report-issue" title="Report a bug on GitHub">${x.bug}</button>
397
400
  <span class="om-pill-brand">
398
401
  <span class="om-pill-text">\u2728OpenMagic\u{1FA84}</span>
399
402
  </span>
@@ -410,7 +413,7 @@
410
413
  <div class="om-panel om-hidden">
411
414
  <div class="om-panel-header">
412
415
  <span class="om-panel-title"></span>
413
- <span class="om-panel-version">v${Ge}</span>
416
+ <span class="om-panel-version">v${Se}</span>
414
417
  <button class="om-panel-clear" data-action="clear-chat" title="Clear chat">${x.trash}</button>
415
418
  <button class="om-panel-close" data-action="close-panel">${x.x}</button>
416
419
  </div>
@@ -431,10 +434,10 @@
431
434
  <button class="om-prompt-send" data-action="prompt-send">${x.send}</button>
432
435
  <input type="file" class="om-file-input om-hidden" accept="image/*" multiple />
433
436
  </div>
434
- </div>`}function mt(e){e.addEventListener("click",n=>{let a=n.target.closest("[data-action]");if(!a)return;n.preventDefault(),n.stopPropagation();let i=a.dataset.action;ft(i,a)}),e.addEventListener("change",n=>{let a=n.target,i=a.dataset.field;i&&(i==="provider"?(o.provider=a.value,o.model=j[o.provider]?.models[0]?.id||"",o.hasApiKey=o.configuredProviders[o.provider]||j[o.provider]?.local||!1,o.saveStatus="",T()):i==="model"&&(o.model=a.value))}),z.addEventListener("keydown",n=>{n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),we())});let t=e.querySelector(".om-file-input");t&&t.addEventListener("change",()=>{xe(t.files),t.value=""});let s=e.querySelector(".om-prompt-row");s&&(s.addEventListener("dragover",n=>{n.preventDefault(),s.style.borderColor="rgba(108, 92, 231, 0.5)"}),s.addEventListener("dragleave",()=>{s.style.borderColor=""}),s.addEventListener("drop",n=>{n.preventDefault(),s.style.borderColor="";let a=n.dataTransfer;a?.files?.length&&xe(a.files)}),z.addEventListener("paste",n=>{let a=n.clipboardData?.items;if(a){for(let i=0;i<a.length;i++)if(a[i].type.startsWith("image/")){let r=a[i].getAsFile();if(r){let d=new DataTransfer;d.items.add(r),xe(d.files)}}}})),Ce(n=>{n.type==="reconnected"&&(o.connected=!0,ve())}),document.addEventListener("keydown",n=>{if((n.ctrlKey||n.metaKey)&&n.shiftKey&&(n.key==="O"||n.key==="o")){if(n.preventDefault(),o.minimized){o.minimized=!1,$.querySelectorAll(".om-pill-btn:not([data-action='minimize']), .om-pill-divider, .om-status-dot").forEach(r=>r.style.display="");let i=w.querySelector(".om-prompt-row");i&&i.classList.remove("om-hidden")}else o.panelOpen?se():O("chat");return}if(n.key==="Escape"){if(o.selecting)return;o.panelOpen&&(se(),n.preventDefault())}}),z.addEventListener("keydown",n=>{(n.ctrlKey||n.metaKey)&&n.key==="Enter"&&(n.preventDefault(),we())})}function Ve(e){return o.roots.length>0?o.roots[0]+"/"+e:e}function ut(e,t){let s=t.split(`
435
- `).map(r=>r.trim()).filter(r=>r.length>0);if(s.length===0)return null;let n=e.split(`
436
- `),a=s[0],i=s[s.length-1];for(let r=0;r<n.length;r++){if(n[r].trim()!==a||r+s.length>n.length)continue;let d=!0;for(let l=0;l<s.length;l++)if(n[r+l].trim()!==s[l]){d=!1;break}if(d){let l=0;for(let c=0;c<r;c++)l+=n[c].length+1;let p=l;for(let c=r;c<r+s.length;c++)p+=n[c].length+1;return p>0&&p<=e.length&&e[p-1]===`
437
- `&&p--,{start:l,end:p}}}return null}async function Fe(e){let t=e.dataset.file,s=e.dataset.search,n=e.dataset.replace;if(!t||!s||!n)return;e.disabled=!0,e.innerHTML='<span class="om-spinner"></span>',e.style.opacity="0.5",e.style.pointerEvents="none";let a=e.closest(".om-diff-card");if(a){let l=a.querySelector(".om-diff-actions");l&&(l.innerHTML='<span class="om-spinner"></span> Applying...')}await new Promise(l=>requestAnimationFrame(l));let i,r;try{i=oe(s),r=oe(n)}catch{o.messages.push({role:"system",content:`Failed to decode diff data for ${t}`}),T();return}let d=Ve(t);try{if(!i&&r){if((await E("fs.write",{path:d,content:r}))?.payload?.ok===!1)o.messages.push({role:"system",content:`Write failed: ${t}`});else{let y=a?.dataset.diffIdx;y!==void 0?o.messages[parseInt(y)]={role:"system",content:`Created ${t}`}:o.messages.push({role:"system",content:`Created ${t}`})}T(),F();return}let l,p=d,c=[d];t!==d&&c.push(t);let f=t.split("/").pop()||t,m=o.roots[0]||"",b=m?`${m}/${f}`:f;b!==d&&b!==t&&c.push(b);for(let u of c){let h=(await E("fs.read",{path:u}).catch(()=>null))?.payload?.content;if(h!=null&&String(h).length>0){l=String(h),p=u;break}}if(!l)o.messages.push({role:"system",content:`Could not read ${t} \u2014 tried: ${c.join(", ")}`});else{let u=l.split(i).length-1;if(u===1){let y=await E("fs.write",{path:p,content:l.replace(i,r)});if(y?.payload?.ok===!1)o.messages.push({role:"system",content:`Write failed: ${t} - ${y.payload?.error||"unknown"}`});else{let h=a?.dataset.diffIdx;h!==void 0?o.messages[parseInt(h)]={role:"system",content:`Applied change to ${t}. Reloading...`}:o.messages.push({role:"system",content:`Applied change to ${t}. Reloading...`})}}else if(u>1)o.messages.push({role:"system",content:`Found ${u} exact matches in ${t} \u2014 expected 1. Edit not applied.`});else{let y=ut(l,i);if(y){let h=l.slice(0,y.start)+r+l.slice(y.end),S=await E("fs.write",{path:p,content:h});if(S?.payload?.ok===!1)o.messages.push({role:"system",content:`Write failed: ${t} - ${S.payload?.error||"unknown"}`});else{let k=a?.dataset.diffIdx;k!==void 0?o.messages[parseInt(k)]={role:"system",content:`Applied change to ${t} (fuzzy match). Reloading...`}:o.messages.push({role:"system",content:`Applied change to ${t} (fuzzy match). Reloading...`})}}else o.messages.push({role:"system",content:`No matching code found in ${t}. The file may have changed since the suggestion.`})}}}catch(l){o.messages.push({role:"system",content:`Failed to apply: ${t} \u2014 ${l.message}`})}T(),F(),setTimeout(()=>{window.location.reload()},1500)}function Ue(e){e.disabled=!0,e.style.opacity="0.5";let t=e.dataset.idx;if(t!==void 0){let s=parseInt(t);try{let n=JSON.parse(oe(o.messages[s]?.content.slice(8)||""));o.messages[s]={role:"system",content:`Rejected change to ${n.file||"file"}`}}catch{o.messages[s]={role:"system",content:"Change rejected"}}}T(),F()}function gt(e){let t=w.querySelector(".om-apply-bar");if(t)if(e>0){t.classList.remove("om-hidden");let s=t.querySelector(".om-apply-bar-text");s&&(s.textContent=`${e} change${e>1?"s":""} ready`)}else t.classList.add("om-hidden")}function Ke(){let e=w.querySelector(".om-apply-bar");e&&e.classList.add("om-hidden")}async function ht(e){let t=e.dataset.file;if(!t)return;let s=Ve(t),n=s+".openmagic-backup";try{let i=(await E("fs.read",{path:n}))?.payload?.content;i?(await E("fs.write",{path:s,content:i}),o.messages.push({role:"system",content:`Reverted change to ${t}`})):o.messages.push({role:"system",content:`No backup found for ${t}`})}catch{o.messages.push({role:"system",content:`Could not revert ${t} \u2014 backup may not exist`})}T()}function ft(e,t){switch(e){case"select":kt();break;case"screenshot":St();break;case"chat":be("chat");break;case"settings":be("settings");break;case"close-panel":se();break;case"prompt-send":we();break;case"save-settings":xt();break;case"get-key":{let s=t.dataset.url;s&&window.open(s,"_blank","noopener");break}case"change-key":{let s=w.querySelector("[data-key-change]");s&&s.classList.remove("om-hidden"),t.style.display="none";break}case"network":be("chat"),vt();break;case"attach-image":wt();break;case"remove-attachment":{let s=parseInt(t.dataset.idx||"0",10);o.attachments.splice(s,1),Ee();break}case"apply-diff":Fe(t);break;case"reject-diff":Ue(t);break;case"apply-all":{let s=w.querySelectorAll('[data-action="apply-diff"]');for(let n of Array.from(s))Fe(n);Ke();break}case"reject-all":{let s=w.querySelectorAll('[data-action="reject-diff"]');for(let n of Array.from(s))Ue(n);Ke();break}case"undo-diff":ht(t);break;case"clear-chat":{o.messages=[];try{sessionStorage.removeItem("__om_state__")}catch{}T();break}case"copy-msg":{let s=parseInt(t.dataset.idx||"0",10),n=o.messages[s];if(n){try{navigator.clipboard.writeText(n.content)}catch{}t.innerHTML=x.check,setTimeout(()=>{t.innerHTML=x.copy},1500)}break}case"clear-element":o.selectedElement=null,X();break;case"clear-screenshot":o.screenshot=null,X();break;case"minimize":{o.minimized=!o.minimized;let s=w.querySelector(".om-panel"),n=w.querySelector(".om-prompt-row"),a=w.querySelector(".om-prompt-attachments"),i=$.querySelectorAll(".om-pill-btn:not([data-action='minimize']), .om-pill-divider, .om-status-dot");o.minimized?(s&&s.classList.add("om-hidden"),n&&n.classList.add("om-hidden"),a&&a.classList.add("om-hidden"),i.forEach(r=>r.style.display="none")):(n&&n.classList.remove("om-hidden"),a&&a.classList.remove("om-hidden"),i.forEach(r=>r.style.display=""),o.panelOpen&&o.activePanel&&s&&s.classList.remove("om-hidden"));break}}}function ve(){let e=w.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${o.connected?"connected":"disconnected"}`)}function J(){w.querySelectorAll(".om-pill-btn").forEach(e=>{let t=e.dataset.action;e.classList.toggle("active",t===o.activePanel||t==="select"&&o.selecting)})}function X(){let e=[];o.selectedElement&&e.push(`<span class="om-prompt-chip">${o.selectedElement.tagName}${o.selectedElement.id?"#"+o.selectedElement.id:""} <button class="om-prompt-chip-x" data-action="clear-element">${x.x}</button></span>`),o.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${x.x}</button></span>`),o.attachments.length&&e.push(`<span class="om-prompt-chip">${o.attachments.length} image${o.attachments.length>1?"s":""}</span>`),o.groundedFiles.length&&e.push(`<span class="om-prompt-chip">${o.groundedFiles.length} files grounded</span>`),We.innerHTML=e.join("")}function O(e){o.panelOpen=!0,o.activePanel=e,Se.classList.remove("om-hidden");let t=w.querySelector(".om-panel-title");t&&(t.textContent=e==="settings"?"Settings":"Chat"),T(),J()}function se(){o.panelOpen=!1,o.activePanel="",Se.classList.add("om-hidden"),J()}function be(e){o.panelOpen&&o.activePanel===e?se():O(e)}function T(){o.activePanel==="settings"?R.innerHTML=yt():o.activePanel==="chat"&&(R.innerHTML=bt(),F()),ct()}function yt(){let e=Object.entries(j).map(([b,u])=>{let h=o.configuredProviders[b]||u.local?" \u2713":"";return`<option value="${b}" ${o.provider===b?"selected":""}>${u.name}${h}</option>`}).join(""),t=j[o.provider],s=t?t.models.map(b=>`<option value="${b.id}" ${o.model===b.id?"selected":""}>${b.name}</option>`).join(""):'<option value="">Select provider first</option>',n=t?.local||!1,a=t?.keyUrl||"",i=t?.keyPlaceholder||"Enter API key...",r=o.configuredProviders[o.provider]||!1,d=o.updateAvailable?`<div class="om-update-banner">v${o.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",l=r||n?`<div class="om-status om-status-success">${x.check} ${t?.name||"Provider"} connected</div>`:"",p=o.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':o.saveStatus==="saved"?`${x.check} Saved`:"Save",c=o.saveStatus==="saving"?"om-btn om-btn-saving":o.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",f=o.saveStatus==="saving"?"disabled":"",m="";return!n&&o.provider&&(r?m=`
437
+ </div>`}function ut(e){e.addEventListener("click",o=>{let r=o.target.closest("[data-action]");if(!r)return;o.preventDefault(),o.stopPropagation();let i=r.dataset.action;yt(i,r)}),e.addEventListener("change",o=>{let r=o.target,i=r.dataset.field;i&&(i==="provider"?(n.provider=r.value,n.model=B[n.provider]?.models[0]?.id||"",n.hasApiKey=n.configuredProviders[n.provider]||B[n.provider]?.local||!1,n.saveStatus="",M()):i==="model"&&(n.model=r.value))}),z.addEventListener("keydown",o=>{o.key==="Enter"&&!o.shiftKey&&(o.preventDefault(),we())});let t=e.querySelector(".om-file-input");t&&t.addEventListener("change",()=>{xe(t.files),t.value=""});let s=e.querySelector(".om-prompt-row");s&&(s.addEventListener("dragover",o=>{o.preventDefault(),s.style.borderColor="rgba(108, 92, 231, 0.5)"}),s.addEventListener("dragleave",()=>{s.style.borderColor=""}),s.addEventListener("drop",o=>{o.preventDefault(),s.style.borderColor="";let r=o.dataTransfer;r?.files?.length&&xe(r.files)}),z.addEventListener("paste",o=>{let r=o.clipboardData?.items;if(r){for(let i=0;i<r.length;i++)if(r[i].type.startsWith("image/")){let a=r[i].getAsFile();if(a){let c=new DataTransfer;c.items.add(a),xe(c.files)}}}})),He(o=>{o.type==="reconnected"&&(n.connected=!0,ve())}),document.addEventListener("keydown",o=>{if((o.ctrlKey||o.metaKey)&&o.shiftKey&&(o.key==="O"||o.key==="o")){if(o.preventDefault(),n.minimized){n.minimized=!1,E.querySelectorAll(".om-pill-btn:not([data-action='minimize']), .om-pill-divider, .om-status-dot").forEach(a=>a.style.display="");let i=w.querySelector(".om-prompt-row");i&&i.classList.remove("om-hidden")}else n.panelOpen?re():O("chat");return}if(o.key==="Escape"){if(n.selecting)return;n.panelOpen&&(re(),o.preventDefault())}}),z.addEventListener("keydown",o=>{(o.ctrlKey||o.metaKey)&&o.key==="Enter"&&(o.preventDefault(),we())})}function Xe(e){return n.roots.length>0?n.roots[0]+"/"+e:e}function ht(e,t){let s=t.split(`
438
+ `).map(a=>a.trim()).filter(a=>a.length>0);if(s.length===0)return null;let o=e.split(`
439
+ `),r=s[0],i=s[s.length-1];for(let a=0;a<o.length;a++){if(o[a].trim()!==r||a+s.length>o.length)continue;let c=!0;for(let l=0;l<s.length;l++)if(o[a+l].trim()!==s[l]){c=!1;break}if(c){let l=0;for(let d=0;d<a;d++)l+=o[d].length+1;let p=l;for(let d=a;d<a+s.length;d++)p+=o[d].length+1;return p>0&&p<=e.length&&e[p-1]===`
440
+ `&&p--,{start:l,end:p}}}return null}async function Ue(e){let t=e.dataset.file,s=e.dataset.search,o=e.dataset.replace;if(!t||!s||!o)return;e.disabled=!0,e.innerHTML='<span class="om-spinner"></span>',e.style.opacity="0.5",e.style.pointerEvents="none";let r=e.closest(".om-diff-card");if(r){let l=r.querySelector(".om-diff-actions");l&&(l.innerHTML='<span class="om-spinner"></span> Applying...')}await new Promise(l=>requestAnimationFrame(l));let i,a;try{i=ae(s),a=ae(o)}catch{n.messages.push({role:"system",content:`Failed to decode diff data for ${t}`}),M();return}let c=Xe(t);try{if(!i&&a){if((await $("fs.write",{path:c,content:a}))?.payload?.ok===!1)n.messages.push({role:"system",content:`Write failed: ${t}`});else{let y=r?.dataset.diffIdx;y!==void 0?n.messages[parseInt(y)]={role:"system",content:`Created ${t}`}:n.messages.push({role:"system",content:`Created ${t}`})}M(),F();return}let l,p=c,d=[c];t!==c&&d.push(t);let f=t.split("/").pop()||t,m=n.roots[0]||"",b=m?`${m}/${f}`:f;b!==c&&b!==t&&d.push(b);for(let u of d){let g=(await $("fs.read",{path:u}).catch(()=>null))?.payload?.content;if(g!=null&&String(g).length>0){l=String(g),p=u;break}}if(!l)n.messages.push({role:"system",content:`Could not read ${t} \u2014 tried: ${d.join(", ")}`});else{let u=l.split(i).length-1;if(u===1){let y=await $("fs.write",{path:p,content:l.replace(i,a)});if(y?.payload?.ok===!1)n.messages.push({role:"system",content:`Write failed: ${t} - ${y.payload?.error||"unknown"}`});else{let g=r?.dataset.diffIdx;g!==void 0?n.messages[parseInt(g)]={role:"system",content:`Applied change to ${t}. Reloading...`}:n.messages.push({role:"system",content:`Applied change to ${t}. Reloading...`})}}else if(u>1)n.messages.push({role:"system",content:`Found ${u} exact matches in ${t} \u2014 expected 1. Edit not applied.`});else{let y=ht(l,i);if(y){let g=l.slice(0,y.start)+a+l.slice(y.end),S=await $("fs.write",{path:p,content:g});if(S?.payload?.ok===!1)n.messages.push({role:"system",content:`Write failed: ${t} - ${S.payload?.error||"unknown"}`});else{let k=r?.dataset.diffIdx;k!==void 0?n.messages[parseInt(k)]={role:"system",content:`Applied change to ${t} (fuzzy match). Reloading...`}:n.messages.push({role:"system",content:`Applied change to ${t} (fuzzy match). Reloading...`})}}else n.messages.push({role:"system",content:`No matching code found in ${t}. The file may have changed since the suggestion.`})}}}catch(l){n.messages.push({role:"system",content:`Failed to apply: ${t} \u2014 ${l.message}`})}M(),F(),setTimeout(()=>{window.location.reload()},1500)}function Ge(e){e.disabled=!0,e.style.opacity="0.5";let t=e.dataset.idx;if(t!==void 0){let s=parseInt(t);try{let o=JSON.parse(ae(n.messages[s]?.content.slice(8)||""));n.messages[s]={role:"system",content:`Rejected change to ${o.file||"file"}`}}catch{n.messages[s]={role:"system",content:"Change rejected"}}}M(),F()}function gt(e){let t=w.querySelector(".om-apply-bar");if(t)if(e>0){t.classList.remove("om-hidden");let s=t.querySelector(".om-apply-bar-text");s&&(s.textContent=`${e} change${e>1?"s":""} ready`)}else t.classList.add("om-hidden")}function Ke(){let e=w.querySelector(".om-apply-bar");e&&e.classList.add("om-hidden")}async function ft(e){let t=e.dataset.file;if(!t)return;let s=Xe(t),o=s+".openmagic-backup";try{let i=(await $("fs.read",{path:o}))?.payload?.content;i?(await $("fs.write",{path:s,content:i}),n.messages.push({role:"system",content:`Reverted change to ${t}`})):n.messages.push({role:"system",content:`No backup found for ${t}`})}catch{n.messages.push({role:"system",content:`Could not revert ${t} \u2014 backup may not exist`})}M()}function yt(e,t){switch(e){case"select":St();break;case"screenshot":$t();break;case"chat":be("chat");break;case"settings":be("settings");break;case"close-panel":re();break;case"prompt-send":we();break;case"save-settings":vt();break;case"get-key":{let s=t.dataset.url;s&&window.open(s,"_blank","noopener");break}case"change-key":{let s=w.querySelector("[data-key-change]");s&&s.classList.remove("om-hidden"),t.style.display="none";break}case"network":be("chat"),wt();break;case"attach-image":kt();break;case"remove-attachment":{let s=parseInt(t.dataset.idx||"0",10);n.attachments.splice(s,1),Ee();break}case"apply-diff":Ue(t);break;case"reject-diff":Ge(t);break;case"apply-all":{let s=w.querySelectorAll('[data-action="apply-diff"]');for(let o of Array.from(s))Ue(o);Ke();break}case"reject-all":{let s=w.querySelectorAll('[data-action="reject-diff"]');for(let o of Array.from(s))Ge(o);Ke();break}case"undo-diff":ft(t);break;case"clear-chat":{n.messages=[];try{sessionStorage.removeItem("__om_state__")}catch{}M();break}case"copy-msg":{let s=parseInt(t.dataset.idx||"0",10),o=We(s);try{navigator.clipboard.writeText(o)}catch{}t.innerHTML=x.check,setTimeout(()=>{t.innerHTML=x.copy},1500);break}case"report-issue":{let s=We();try{navigator.clipboard.writeText(s)}catch{}window.open("https://github.com/Kalmuraee/OpenMagic/issues/new?template=bug_report.yml","_blank","noopener"),n.messages.push({role:"system",content:"Debug info copied to clipboard. Paste it in the Debug Info field on GitHub."}),n.panelOpen&&M();break}case"clear-element":n.selectedElement=null,X();break;case"clear-screenshot":n.screenshot=null,X();break;case"minimize":{n.minimized=!n.minimized;let s=w.querySelector(".om-panel"),o=w.querySelector(".om-prompt-row"),r=w.querySelector(".om-prompt-attachments"),i=E.querySelectorAll(".om-pill-btn:not([data-action='minimize']), .om-pill-divider, .om-status-dot");n.minimized?(s&&s.classList.add("om-hidden"),o&&o.classList.add("om-hidden"),r&&r.classList.add("om-hidden"),i.forEach(a=>a.style.display="none")):(o&&o.classList.remove("om-hidden"),r&&r.classList.remove("om-hidden"),i.forEach(a=>a.style.display=""),n.panelOpen&&n.activePanel&&s&&s.classList.remove("om-hidden"));break}}}function ve(){let e=w.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${n.connected?"connected":"disconnected"}`)}function J(){w.querySelectorAll(".om-pill-btn").forEach(e=>{let t=e.dataset.action;e.classList.toggle("active",t===n.activePanel||t==="select"&&n.selecting)})}function X(){let e=[];n.selectedElement&&e.push(`<span class="om-prompt-chip">${n.selectedElement.tagName}${n.selectedElement.id?"#"+n.selectedElement.id:""} <button class="om-prompt-chip-x" data-action="clear-element">${x.x}</button></span>`),n.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${x.x}</button></span>`),n.attachments.length&&e.push(`<span class="om-prompt-chip">${n.attachments.length} image${n.attachments.length>1?"s":""}</span>`),n.groundedFiles.length&&e.push(`<span class="om-prompt-chip">${n.groundedFiles.length} files grounded</span>`),Ve.innerHTML=e.join("")}function O(e){n.panelOpen=!0,n.activePanel=e,$e.classList.remove("om-hidden");let t=w.querySelector(".om-panel-title");t&&(t.textContent=e==="settings"?"Settings":"Chat"),M(),J()}function re(){n.panelOpen=!1,n.activePanel="",$e.classList.add("om-hidden"),J()}function be(e){n.panelOpen&&n.activePanel===e?re():O(e)}function M(){n.activePanel==="settings"?R.innerHTML=bt():n.activePanel==="chat"&&(R.innerHTML=xt(),F()),dt()}function bt(){let e=Object.entries(B).map(([b,u])=>{let g=n.configuredProviders[b]||u.local?" \u2713":"";return`<option value="${b}" ${n.provider===b?"selected":""}>${u.name}${g}</option>`}).join(""),t=B[n.provider],s=t?t.models.map(b=>`<option value="${b.id}" ${n.model===b.id?"selected":""}>${b.name}</option>`).join(""):'<option value="">Select provider first</option>',o=t?.local||!1,r=t?.keyUrl||"",i=t?.keyPlaceholder||"Enter API key...",a=n.configuredProviders[n.provider]||!1,c=n.updateAvailable?`<div class="om-update-banner">v${n.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",l=a||o?`<div class="om-status om-status-success">${x.check} ${t?.name||"Provider"} connected</div>`:"",p=n.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':n.saveStatus==="saved"?`${x.check} Saved`:"Save",d=n.saveStatus==="saving"?"om-btn om-btn-saving":n.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",f=n.saveStatus==="saving"?"disabled":"",m="";return!o&&n.provider&&(a?m=`
438
441
  <div class="om-field">
439
442
  <label class="om-label">API Key</label>
440
443
  <div class="om-key-configured">
@@ -444,7 +447,7 @@
444
447
  <div class="om-key-change-row om-hidden" data-key-change>
445
448
  <div class="om-key-row">
446
449
  <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" />
447
- ${a?`<button class="om-btn-get-key" data-action="get-key" data-url="${a}">${x.externalLink} Get key</button>`:""}
450
+ ${r?`<button class="om-btn-get-key" data-action="get-key" data-url="${r}">${x.externalLink} Get key</button>`:""}
448
451
  </div>
449
452
  </div>
450
453
  </div>`:m=`
@@ -452,11 +455,11 @@
452
455
  <label class="om-label">API Key</label>
453
456
  <div class="om-key-row">
454
457
  <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" />
455
- ${a?`<button class="om-btn-get-key" data-action="get-key" data-url="${a}">${x.externalLink} Get key</button>`:""}
458
+ ${r?`<button class="om-btn-get-key" data-action="get-key" data-url="${r}">${x.externalLink} Get key</button>`:""}
456
459
  </div>
457
- ${a?`<div class="om-key-hint"><a data-action="get-key" data-url="${a}">Get your ${t?.name||""} API key here</a></div>`:""}
460
+ ${r?`<div class="om-key-hint"><a data-action="get-key" data-url="${r}">Get your ${t?.name||""} API key here</a></div>`:""}
458
461
  </div>`),`
459
- ${d}
462
+ ${c}
460
463
  <div class="om-settings">
461
464
  <div class="om-field">
462
465
  <label class="om-label">Provider</label>
@@ -467,27 +470,28 @@
467
470
  <select class="om-select" data-field="model"><option value="">Select Model...</option>${s}</select>
468
471
  </div>
469
472
  ${m}
470
- <button class="${c}" data-action="save-settings" ${f}>${p}</button>
473
+ <button class="${d}" data-action="save-settings" ${f}>${p}</button>
471
474
  ${l}
472
- </div>`}function bt(){if(!o.provider||!o.hasApiKey&&!j[o.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=o.messages.map((n,a)=>{if(n.content.startsWith("__DIFFGROUP__"))return"";if(n.content.startsWith("__DIFF__"))try{let r=JSON.parse(oe(n.content.slice(8))),d=r.type==="create"||!r.search&&r.replace,l=ne(r.search||""),p=ne(r.replace||"");return`<div class="om-diff-card" data-diff-idx="${a}">
473
- <div class="om-diff-file">${A(d?"Create new file":"Edit")}: ${A(r.file)}</div>
474
- ${r.search?`<div class="om-diff-removed">${A(r.search.slice(0,200))}</div>`:""}
475
- <div class="om-diff-added">${A((r.replace||"").slice(0,300))}</div>
475
+ </div>`}function xt(){if(!n.provider||!n.hasApiKey&&!B[n.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=n.messages.map((o,r)=>{if(o.content.startsWith("__DIFFGROUP__"))return"";if(o.content.startsWith("__DIFF__"))try{let a=JSON.parse(ae(o.content.slice(8))),c=a.type==="create"||!a.search&&a.replace,l=se(a.search||""),p=se(a.replace||"");return`<div class="om-diff-card" data-diff-idx="${r}">
476
+ <div class="om-diff-file">${A(c?"Create new file":"Edit")}: ${A(a.file)}</div>
477
+ ${a.search?`<div class="om-diff-removed">${A(a.search.slice(0,200))}</div>`:""}
478
+ <div class="om-diff-added">${A((a.replace||"").slice(0,300))}</div>
476
479
  <div class="om-diff-actions">
477
- <button class="om-btn om-btn-sm" data-action="apply-diff" data-file="${A(r.file)}" data-search="${l}" data-replace="${p}">Apply</button>
478
- <button class="om-btn-secondary om-btn-sm" data-action="reject-diff" data-idx="${a}">Reject</button>
480
+ <button class="om-btn om-btn-sm" data-action="apply-diff" data-file="${A(a.file)}" data-search="${l}" data-replace="${p}">Apply</button>
481
+ <button class="om-btn-secondary om-btn-sm" data-action="reject-diff" data-idx="${r}">Reject</button>
479
482
  </div>
480
- </div>`}catch{return'<div class="om-msg om-msg-system">Malformed diff data</div>'}if(n.content.startsWith("Applied change to ")){let r=n.content.replace("Applied change to ","").replace(/ \(fuzzy match.*?\)/g,"").replace(". Reloading...","");return`<div class="om-msg om-msg-system">${A(n.content)} <button class="om-undo-btn" data-action="undo-diff" data-file="${A(r)}">Undo</button></div>`}let i=n.role==="user"||n.role==="assistant"?`<button class="om-copy-btn" data-action="copy-msg" data-idx="${a}" title="Copy">${x.copy}</button>`:"";return n.role==="assistant"?`<div class="om-msg om-msg-assistant">${$t(n.content)}${i}</div>`:`<div class="om-msg om-msg-${n.role}">${A(n.content)}${i}</div>`}).join(""),t=o.streaming?'<div class="om-msg om-msg-assistant"><span class="om-spinner"></span> Generating response...</div>':"";return`<div class="om-chat-messages">${!o.messages.length&&!o.streaming?'<div class="om-chat-empty">Select an element or type below to start</div>':""}${e}${t}</div>`}function F(){requestAnimationFrame(()=>{let e=R.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function xt(){let t=R.querySelector('[data-field="apiKey"]')?.value||"";if(!o.provider){o.saveStatus="error",te(),setTimeout(()=>{o.saveStatus="",T()},2e3);return}if(!He()){o.saveStatus="error",te();let n=R.querySelector('[data-action="save-settings"]');n&&(n.innerHTML="Not connected - check terminal"),setTimeout(()=>{o.saveStatus="",T()},3e3);return}let s={provider:o.provider,model:o.model};t&&(s.apiKey=t),o.saveStatus="saving",te();try{let n=await Promise.race([E("config.set",s),new Promise((a,i)=>setTimeout(()=>i(new Error("Save timed out")),8e3))]);t&&o.provider&&(o.configuredProviders[o.provider]=!0),o.hasApiKey=!!(t||o.configuredProviders[o.provider]),o.saveStatus="saved",te(),setTimeout(()=>{o.saveStatus="",o.activePanel==="settings"&&O("chat")},1200)}catch(n){o.saveStatus="error";let a=R.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"}`;a&&(a.innerHTML=i,a.className="om-btn",a.disabled=!1),setTimeout(()=>{o.saveStatus="",T()},4e3)}}function te(){let e=R.querySelector('[data-action="save-settings"]');e&&(o.saveStatus==="saving"?(e.innerHTML='<span class="om-spinner"></span> Saving...',e.className="om-btn om-btn-saving",e.disabled=!0):o.saveStatus==="saved"?(e.innerHTML=`${x.check} Saved`,e.className="om-btn om-btn-saved",e.disabled=!1):o.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 we(){let e=z.value.trim();if(!e||o.streaming)return;if(!o.provider||!o.hasApiKey&&!j[o.provider]?.local){O("settings");return}o.messages.push({role:"user",content:e}),o.streaming=!0,o.streamContent="",z.value="",O("chat");let t=Be(o.selectedElement,o.screenshot);t.pageUrl=window.location.href,t.pageTitle=document.title,o.attachments.length>0&&(t.screenshot||(t.screenshot=o.attachments[0]),t.attachments=[...o.attachments]);let s=5,n=32e3,a=/\.(?:[cm]?[jt]sx?|svelte|vue|astro|html?|css|scss|less|php|py)$/i,i=R.querySelector(".om-msg-assistant:last-child");i&&(i.innerHTML='<span class="om-spinner"></span> Reading project files...');try{let l=await E("fs.list",{});l?.payload?.projectTree&&(t.projectTree=l.payload.projectTree);let c=(l?.payload?.files||[]).filter(g=>g.type==="file"&&a.test(g.path)),f=[e];if(o.selectedElement&&(o.selectedElement.id&&f.push(o.selectedElement.id),o.selectedElement.className&&f.push(o.selectedElement.className),o.selectedElement.textContent&&f.push(o.selectedElement.textContent.slice(0,100)),o.selectedElement.componentHint&&f.push(o.selectedElement.componentHint),o.selectedElement.ancestry))for(let g of o.selectedElement.ancestry)f.push(g);let m=f.filter(Boolean).join(" ").toLowerCase().split(/[^a-z0-9_-]+/).filter(g=>g.length>=2&&!["the","to","in","of","and","div","span","class","style"].includes(g)),u=window.location.pathname.split("/").filter(g=>g.length>1&&!/^\d+$/.test(g)),y=c.map(g=>{let v=0,L=g.path.toLowerCase();for(let N of u)L.includes(N.toLowerCase())&&(v+=15);if(o.selectedElement?.componentHint){let N=o.selectedElement.componentHint.toLowerCase();L.includes(N)&&(v+=12)}for(let N of m)L.includes(N)&&(v+=5);return/(component|page|route|layout|template|view)/.test(L)&&(v+=3),/page\.[jt]sx?$|layout\.[jt]sx?$|\+page\.svelte$/.test(L)&&(v+=5),{...g,score:v}}).sort((g,v)=>v.score-g.score),h=[],S=new Set,k=0;for(let g of y.slice(0,s)){if(g.score<=0||k>=n)break;try{let v=o.roots[0]||"",L=v?`${v}/${g.path}`:g.path,N=await E("fs.read",{path:L}),D=String(N?.payload?.content||"");if(!D)continue;let U=Math.min(8e3,n-k),re=D.slice(0,U);D.length>U&&(re+=`
481
- // [FILE TRUNCATED \u2014 showing ${U} of ${D.length} chars]`),h.push({path:g.path,content:re}),S.add(g.path),k+=re.length;let Xe=g.path.replace(/\.[^.]+$/,""),Je=[".module.css",".module.scss",".css",".scss",".styles.ts"];for(let ie of Je){let M=Xe+ie;if(S.has(M)||k>=n)continue;if(c.find(K=>K.path===M)){try{let K=await E("fs.read",{path:v?`${v}/${M}`:M}),P=String(K?.payload?.content||"");if(P){let Y=Math.min(4e3,n-k),I=P.slice(0,Y);P.length>Y&&(I+=`
482
- // [FILE TRUNCATED \u2014 showing ${Y} of ${P.length} chars]`),h.push({path:M,content:I}),S.add(M),k+=I.length}}catch{}break}}let Ye=D.matchAll(/(?:import|from)\s+['"]\.?\.\/([\w/.-]+)['"]/g);for(let ie of Ye){if(k>=n)break;let M=ie[1],q=g.path.replace(/\/[^/]+$/,""),K=[`${q}/${M}`,`${q}/${M}.tsx`,`${q}/${M}.ts`,`${q}/${M}.jsx`,`${q}/${M}.js`,`${q}/${M}/index.tsx`,`${q}/${M}/index.ts`];for(let P of K){if(S.has(P))break;if(c.find(I=>I.path===P)){try{let I=await E("fs.read",{path:v?`${v}/${P}`:P}),Z=String(I?.payload?.content||"");if(Z){let le=Math.min(8e3,n-k),ce=Z.slice(0,le);Z.length>le&&(ce+=`
483
- // [FILE TRUNCATED \u2014 showing ${le} of ${Z.length} chars]`),h.push({path:P,content:ce}),S.add(P),k+=ce.length}}catch{}break}}}}catch{}}if(k<n)try{let g=o.roots[0]||"",v=await E("fs.read",{path:g?`${g}/package.json`:"package.json"}),L=String(v?.payload?.content||"");if(L)try{let N=JSON.parse(L),D={...N.dependencies,...N.devDependencies},U=JSON.stringify(D,null,2);h.push({path:"package.json (dependencies)",content:U.slice(0,2e3)})}catch{h.push({path:"package.json",content:L.slice(0,2e3)})}}catch{}if(h.length){t.files=h;let g=h.map(v=>v.path.split("/").pop()).join(", ");i&&(i.innerHTML=`<span class="om-spinner"></span> Thinking... (${h.length} files: ${g})`)}o.groundedFiles=h.map(g=>g.path)}catch{}let r=4,d=0;try{for(;d<=r;){o.streamContent="";let l=await Te("llm.chat",{provider:o.provider,model:o.model,messages:o.messages.map(m=>({role:m.role,content:m.content})),context:t},m=>{o.streamContent+=m}),p=o.streamContent||l?.content||"",c=p.match(/NEED_FILE:\s*"?([^\s"}\]]+)"?/)||p.match(/(?:need|provide|show|read|see|contents?\s+of)\s+(?:the\s+)?(?:file\s+)?[`"']?([a-zA-Z0-9_/.@-]+\.[a-z]{1,5})[`"']?/i)||p.match(/(?:source\s+(?:file|code)\s+(?:for|of|at))\s+[`"']?([a-zA-Z0-9_/.@-]+\.[a-z]{1,5})[`"']?/i);if(c&&!l?.modifications?.length&&d<r){let m=c[1].trim();d++;let b=R.querySelector(".om-msg-assistant:last-child");b&&(b.innerHTML=`<span class="om-spinner"></span> Reading ${m}...`);try{let u=o.roots[0]||"",y=u?`${u}/${m}`:m,h,S=[y];m!==y&&S.push(m);let k=m.split("/").pop()||m,g=u?`${u}/${k}`:k;g!==y&&g!==m&&S.push(g);for(let v of S){let L=await E("fs.read",{path:v}).catch(()=>null);if(L?.payload?.content){h=String(L.payload.content);break}}if(h)t.files||(t.files=[]),t.files.push({path:m,content:h.slice(0,8e3)});else{o.messages.push({role:"system",content:`Could not read ${m}`});break}}catch{o.messages.push({role:"system",content:`File not found: ${m}`});break}continue}let f=p;try{let m=JSON.parse(p);m.explanation&&(f=m.explanation)}catch{let m=p.match(/```(?:json)?\s*([\s\S]*?)```/);if(m)try{let b=JSON.parse(m[1]);b.explanation&&(f=b.explanation)}catch{}}if(o.messages.push({role:"assistant",content:f}),l?.modifications?.length){let m=Math.random().toString(36).slice(2),b=l.modifications.filter(u=>u.type==="edit"&&u.file&&u.search&&u.replace||u.type==="create"&&u.file&&u.content);gt(b.length);for(let u of l.modifications)if(u.type==="edit"&&u.file&&u.search&&u.replace){let y=Math.random().toString(36).slice(2),h=JSON.stringify({id:y,file:u.file,search:u.search,replace:u.replace,groupId:m});o.messages.push({role:"system",content:`__DIFF__${ne(h)}`})}else if(u.type==="create"&&u.file&&u.content){let y=Math.random().toString(36).slice(2),h=JSON.stringify({id:y,file:u.file,search:"",replace:u.content,type:"create",groupId:m});o.messages.push({role:"system",content:`__DIFF__${ne(h)}`})}else u.type==="delete"&&u.file&&o.messages.push({role:"system",content:`LLM proposed deleting ${u.file} \u2014 skipped (use edit with search/replace instead)`})}break}}catch(l){o.messages.push({role:"system",content:`Error: ${l.message}`})}o.streaming=!1,o.streamContent="",o.attachments=[],Ee(),T(),F()}function vt(){let e=window.performance,t=e.getEntriesByType("navigation")[0],s=e.getEntriesByType("paint"),n=e.getEntriesByType("resource").slice(-20),a=fe(),i=ye(),r=[];r.push("--- Network & Performance Capture ---"),t&&(r.push(`Page load: ${Math.round(t.loadEventEnd-t.startTime)}ms`),r.push(`DOM ready: ${Math.round(t.domContentLoadedEventEnd-t.startTime)}ms`),r.push(`TTFB: ${Math.round(t.responseStart-t.startTime)}ms`));let d=s.find(l=>l.name==="first-contentful-paint");if(d&&r.push(`FCP: ${Math.round(d.startTime)}ms`),n.length){let l=n.filter(c=>c.initiatorType==="fetch"||c.initiatorType==="xmlhttprequest"),p=l.length>0?l:n;r.push(`
484
- All network requests (${p.length}):`);for(let c of p.slice(-30)){let f=c.name.length>80?"..."+c.name.slice(-77):c.name,m=c.responseStatus||"";r.push(` ${Math.round(c.duration)}ms ${m?`[${m}]`:""} ${f}`)}}if(a.length){r.push(`
485
- Fetch/XHR requests (${a.length}):`);for(let l of a.slice(-20))r.push(` ${l.method} ${l.url.slice(0,80)} \u2192 ${l.status||"pending"} (${l.duration||"?"}ms)`)}if(i.length){let l=i.filter(c=>c.level==="error"),p=i.filter(c=>c.level==="warn");l.length&&r.push(`
486
- Console errors: ${l.length}`),p.length&&r.push(`Console warnings: ${p.length}`)}if(n.length>5){let l=[...n].sort((p,c)=>c.duration-p.duration).slice(0,5);r.push(`
487
- Slowest resources:`);for(let p of l)r.push(` ${Math.round(p.duration)}ms \u2014 ${p.name.split("/").pop()?.slice(0,60)}`)}o.messages.push({role:"system",content:r.join(`
488
- `)}),T(),F(),X()}function wt(){let e=w.querySelector(".om-file-input");e&&e.click()}function xe(e){if(e)for(let t=0;t<e.length&&o.attachments.length<5;t++){let s=e[t];if(!s.type.startsWith("image/")||s.size>10*1024*1024)continue;let n=new FileReader;n.onload=()=>{typeof n.result=="string"&&(o.attachments.push(n.result),Ee())},n.readAsDataURL(s)}}function Ee(){let e=w.querySelector(".om-prompt-attachments");if(e){if(!o.attachments.length){e.innerHTML="",e.classList.add("om-hidden");return}e.classList.remove("om-hidden"),e.innerHTML=o.attachments.map((t,s)=>`<div class="om-attachment-thumb">
483
+ </div>`}catch{return'<div class="om-msg om-msg-system">Malformed diff data</div>'}if(o.content.startsWith("Applied change to ")){let a=o.content.replace("Applied change to ","").replace(/ \(fuzzy match.*?\)/g,"").replace(". Reloading...","");return`<div class="om-msg om-msg-system">${A(o.content)} <button class="om-undo-btn" data-action="undo-diff" data-file="${A(a)}">Undo</button></div>`}let i=o.role==="user"||o.role==="assistant"?`<button class="om-copy-btn" data-action="copy-msg" data-idx="${r}" title="Copy">${x.copy}</button>`:"";return o.role==="assistant"?`<div class="om-msg om-msg-assistant">${Mt(o.content)}${i}</div>`:`<div class="om-msg om-msg-${o.role}">${A(o.content)}${i}</div>`}).join(""),t=n.streaming?'<div class="om-msg om-msg-assistant"><span class="om-spinner"></span> Generating response...</div>':"";return`<div class="om-chat-messages">${!n.messages.length&&!n.streaming?'<div class="om-chat-empty">Select an element or type below to start</div>':""}${e}${t}</div>`}function F(){requestAnimationFrame(()=>{let e=R.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function vt(){let t=R.querySelector('[data-field="apiKey"]')?.value||"";if(!n.provider){n.saveStatus="error",oe(),setTimeout(()=>{n.saveStatus="",M()},2e3);return}if(!Pe()){n.saveStatus="error",oe();let o=R.querySelector('[data-action="save-settings"]');o&&(o.innerHTML="Not connected - check terminal"),setTimeout(()=>{n.saveStatus="",M()},3e3);return}let s={provider:n.provider,model:n.model};t&&(s.apiKey=t),n.saveStatus="saving",oe();try{let o=await Promise.race([$("config.set",s),new Promise((r,i)=>setTimeout(()=>i(new Error("Save timed out")),8e3))]);t&&n.provider&&(n.configuredProviders[n.provider]=!0),n.hasApiKey=!!(t||n.configuredProviders[n.provider]),n.saveStatus="saved",oe(),setTimeout(()=>{n.saveStatus="",n.activePanel==="settings"&&O("chat")},1200)}catch(o){n.saveStatus="error";let r=R.querySelector('[data-action="save-settings"]'),i=(o?.message||"").includes("timeout")?"Connection timeout - is the CLI running?":(o?.message||"").includes("connected")?"Not connected to OpenMagic server":`Save failed: ${o?.message||"Unknown error"}`;r&&(r.innerHTML=i,r.className="om-btn",r.disabled=!1),setTimeout(()=>{n.saveStatus="",M()},4e3)}}function oe(){let e=R.querySelector('[data-action="save-settings"]');e&&(n.saveStatus==="saving"?(e.innerHTML='<span class="om-spinner"></span> Saving...',e.className="om-btn om-btn-saving",e.disabled=!0):n.saveStatus==="saved"?(e.innerHTML=`${x.check} Saved`,e.className="om-btn om-btn-saved",e.disabled=!1):n.saveStatus==="error"?(e.innerHTML="Save failed - try again",e.className="om-btn",e.disabled=!1):(e.innerHTML="Save",e.className="om-btn",e.disabled=!1))}async function we(){let e=z.value.trim();if(!e||n.streaming)return;if(!n.provider||!n.hasApiKey&&!B[n.provider]?.local){O("settings");return}n.messages.push({role:"user",content:e}),n.streaming=!0,n.streamContent="",z.value="",O("chat");let t=je(n.selectedElement,n.screenshot);t.pageUrl=window.location.href,t.pageTitle=document.title,n.attachments.length>0&&(t.screenshot||(t.screenshot=n.attachments[0]),t.attachments=[...n.attachments]);let s=5,o=32e3,r=/\.(?:[cm]?[jt]sx?|svelte|vue|astro|html?|css|scss|less|php|py)$/i,i=R.querySelector(".om-msg-assistant:last-child");i&&(i.innerHTML='<span class="om-spinner"></span> Reading project files...');try{let l=await $("fs.list",{});l?.payload?.projectTree&&(t.projectTree=l.payload.projectTree);let d=(l?.payload?.files||[]).filter(h=>h.type==="file"&&r.test(h.path)),f=[e];if(n.selectedElement&&(n.selectedElement.id&&f.push(n.selectedElement.id),n.selectedElement.className&&f.push(n.selectedElement.className),n.selectedElement.textContent&&f.push(n.selectedElement.textContent.slice(0,100)),n.selectedElement.componentHint&&f.push(n.selectedElement.componentHint),n.selectedElement.ancestry))for(let h of n.selectedElement.ancestry)f.push(h);let m=f.filter(Boolean).join(" ").toLowerCase().split(/[^a-z0-9_-]+/).filter(h=>h.length>=2&&!["the","to","in","of","and","div","span","class","style"].includes(h)),u=window.location.pathname.split("/").filter(h=>h.length>1&&!/^\d+$/.test(h)),y=d.map(h=>{let v=0,L=h.path.toLowerCase();for(let N of u)L.includes(N.toLowerCase())&&(v+=15);if(n.selectedElement?.componentHint){let N=n.selectedElement.componentHint.toLowerCase();L.includes(N)&&(v+=12)}for(let N of m)L.includes(N)&&(v+=5);return/(component|page|route|layout|template|view)/.test(L)&&(v+=3),/page\.[jt]sx?$|layout\.[jt]sx?$|\+page\.svelte$/.test(L)&&(v+=5),{...h,score:v}}).sort((h,v)=>v.score-h.score),g=[],S=new Set,k=0;for(let h of y.slice(0,s)){if(h.score<=0||k>=o)break;try{let v=n.roots[0]||"",L=v?`${v}/${h.path}`:h.path,N=await $("fs.read",{path:L}),D=String(N?.payload?.content||"");if(!D)continue;let U=Math.min(8e3,o-k),le=D.slice(0,U);D.length>U&&(le+=`
484
+ // [FILE TRUNCATED \u2014 showing ${U} of ${D.length} chars]`),g.push({path:h.path,content:le}),S.add(h.path),k+=le.length;let Je=h.path.replace(/\.[^.]+$/,""),Ye=[".module.css",".module.scss",".css",".scss",".styles.ts"];for(let ce of Ye){let T=Je+ce;if(S.has(T)||k>=o)continue;if(d.find(G=>G.path===T)){try{let G=await $("fs.read",{path:v?`${v}/${T}`:T}),P=String(G?.payload?.content||"");if(P){let Y=Math.min(4e3,o-k),I=P.slice(0,Y);P.length>Y&&(I+=`
485
+ // [FILE TRUNCATED \u2014 showing ${Y} of ${P.length} chars]`),g.push({path:T,content:I}),S.add(T),k+=I.length}}catch{}break}}let Ze=D.matchAll(/(?:import|from)\s+['"]\.?\.\/([\w/.-]+)['"]/g);for(let ce of Ze){if(k>=o)break;let T=ce[1],q=h.path.replace(/\/[^/]+$/,""),G=[`${q}/${T}`,`${q}/${T}.tsx`,`${q}/${T}.ts`,`${q}/${T}.jsx`,`${q}/${T}.js`,`${q}/${T}/index.tsx`,`${q}/${T}/index.ts`];for(let P of G){if(S.has(P))break;if(d.find(I=>I.path===P)){try{let I=await $("fs.read",{path:v?`${v}/${P}`:P}),Z=String(I?.payload?.content||"");if(Z){let de=Math.min(8e3,o-k),pe=Z.slice(0,de);Z.length>de&&(pe+=`
486
+ // [FILE TRUNCATED \u2014 showing ${de} of ${Z.length} chars]`),g.push({path:P,content:pe}),S.add(P),k+=pe.length}}catch{}break}}}}catch{}}if(k<o)try{let h=n.roots[0]||"",v=await $("fs.read",{path:h?`${h}/package.json`:"package.json"}),L=String(v?.payload?.content||"");if(L)try{let N=JSON.parse(L),D={...N.dependencies,...N.devDependencies},U=JSON.stringify(D,null,2);g.push({path:"package.json (dependencies)",content:U.slice(0,2e3)})}catch{g.push({path:"package.json",content:L.slice(0,2e3)})}}catch{}if(g.length){t.files=g;let h=g.map(v=>v.path.split("/").pop()).join(", ");i&&(i.innerHTML=`<span class="om-spinner"></span> Thinking... (${g.length} files: ${h})`)}n.groundedFiles=g.map(h=>h.path)}catch{}let a=4,c=0;try{for(;c<=a;){n.streamContent="";let l=await Ce("llm.chat",{provider:n.provider,model:n.model,messages:n.messages.map(m=>({role:m.role,content:m.content})),context:t},m=>{n.streamContent+=m}),p=n.streamContent||l?.content||"",d=p.match(/NEED_FILE:\s*"?([^\s"}\]]+)"?/)||p.match(/(?:need|provide|show|read|see|contents?\s+of)\s+(?:the\s+)?(?:file\s+)?[`"']?([a-zA-Z0-9_/.@-]+\.[a-z]{1,5})[`"']?/i)||p.match(/(?:source\s+(?:file|code)\s+(?:for|of|at))\s+[`"']?([a-zA-Z0-9_/.@-]+\.[a-z]{1,5})[`"']?/i);if(d&&!l?.modifications?.length&&c<a){let m=d[1].trim();c++;let b=R.querySelector(".om-msg-assistant:last-child");b&&(b.innerHTML=`<span class="om-spinner"></span> Reading ${m}...`);try{let u=n.roots[0]||"",y=u?`${u}/${m}`:m,g,S=[y];m!==y&&S.push(m);let k=m.split("/").pop()||m,h=u?`${u}/${k}`:k;h!==y&&h!==m&&S.push(h);for(let v of S){let L=await $("fs.read",{path:v}).catch(()=>null);if(L?.payload?.content){g=String(L.payload.content);break}}if(g)t.files||(t.files=[]),t.files.push({path:m,content:g.slice(0,8e3)});else{n.messages.push({role:"system",content:`Could not read ${m}`});break}}catch{n.messages.push({role:"system",content:`File not found: ${m}`});break}continue}let f=p;try{let m=JSON.parse(p);m.explanation&&(f=m.explanation)}catch{let m=p.match(/```(?:json)?\s*([\s\S]*?)```/);if(m)try{let b=JSON.parse(m[1]);b.explanation&&(f=b.explanation)}catch{}}if(n.messages.push({role:"assistant",content:f}),l?.modifications?.length){let m=Math.random().toString(36).slice(2),b=l.modifications.filter(u=>u.type==="edit"&&u.file&&u.search&&u.replace||u.type==="create"&&u.file&&u.content);gt(b.length);for(let u of l.modifications)if(u.type==="edit"&&u.file&&u.search&&u.replace){let y=Math.random().toString(36).slice(2),g=JSON.stringify({id:y,file:u.file,search:u.search,replace:u.replace,groupId:m});n.messages.push({role:"system",content:`__DIFF__${se(g)}`})}else if(u.type==="create"&&u.file&&u.content){let y=Math.random().toString(36).slice(2),g=JSON.stringify({id:y,file:u.file,search:"",replace:u.content,type:"create",groupId:m});n.messages.push({role:"system",content:`__DIFF__${se(g)}`})}else u.type==="delete"&&u.file&&n.messages.push({role:"system",content:`LLM proposed deleting ${u.file} \u2014 skipped (use edit with search/replace instead)`})}break}}catch(l){n.messages.push({role:"system",content:`Error: ${l.message}`})}n.streaming=!1,n.streamContent="",n.attachments=[],Ee(),M(),F()}function wt(){let e=window.performance,t=e.getEntriesByType("navigation")[0],s=e.getEntriesByType("paint"),o=e.getEntriesByType("resource").slice(-20),r=te(),i=ne(),a=[];a.push("--- Network & Performance Capture ---"),t&&(a.push(`Page load: ${Math.round(t.loadEventEnd-t.startTime)}ms`),a.push(`DOM ready: ${Math.round(t.domContentLoadedEventEnd-t.startTime)}ms`),a.push(`TTFB: ${Math.round(t.responseStart-t.startTime)}ms`));let c=s.find(l=>l.name==="first-contentful-paint");if(c&&a.push(`FCP: ${Math.round(c.startTime)}ms`),o.length){let l=o.filter(d=>d.initiatorType==="fetch"||d.initiatorType==="xmlhttprequest"),p=l.length>0?l:o;a.push(`
487
+ All network requests (${p.length}):`);for(let d of p.slice(-30)){let f=d.name.length>80?"..."+d.name.slice(-77):d.name,m=d.responseStatus||"";a.push(` ${Math.round(d.duration)}ms ${m?`[${m}]`:""} ${f}`)}}if(r.length){a.push(`
488
+ Fetch/XHR requests (${r.length}):`);for(let l of r.slice(-20))a.push(` ${l.method} ${l.url.slice(0,80)} \u2192 ${l.status||"pending"} (${l.duration||"?"}ms)`)}if(i.length){let l=i.filter(d=>d.level==="error"),p=i.filter(d=>d.level==="warn");l.length&&a.push(`
489
+ Console errors: ${l.length}`),p.length&&a.push(`Console warnings: ${p.length}`)}if(o.length>5){let l=[...o].sort((p,d)=>d.duration-p.duration).slice(0,5);a.push(`
490
+ Slowest resources:`);for(let p of l)a.push(` ${Math.round(p.duration)}ms \u2014 ${p.name.split("/").pop()?.slice(0,60)}`)}n.messages.push({role:"system",content:a.join(`
491
+ `)}),M(),F(),X()}function kt(){let e=w.querySelector(".om-file-input");e&&e.click()}function xe(e){if(e)for(let t=0;t<e.length&&n.attachments.length<5;t++){let s=e[t];if(!s.type.startsWith("image/")||s.size>10*1024*1024)continue;let o=new FileReader;o.onload=()=>{typeof o.result=="string"&&(n.attachments.push(o.result),Ee())},o.readAsDataURL(s)}}function Ee(){let e=w.querySelector(".om-prompt-attachments");if(e){if(!n.attachments.length){e.innerHTML="",e.classList.add("om-hidden");return}e.classList.remove("om-hidden"),e.innerHTML=n.attachments.map((t,s)=>`<div class="om-attachment-thumb">
489
492
  <img src="${t}" alt="attachment" />
490
493
  <button class="om-attachment-remove" data-action="remove-attachment" data-idx="${s}">${x.x}</button>
491
- </div>`).join("")}}var W=null,V=null;function kt(){o.selecting?ke():ae()}function ae(){o.selecting=!0,document.body.style.cursor="crosshair",J(),V=t=>{let s=t.target;if(s.closest("openmagic-toolbar")||s.dataset?.openmagic)return;let n=s.getBoundingClientRect();Ne({x:n.x,y:n.y,width:n.width,height:n.height})},W=t=>{t.preventDefault(),t.stopPropagation();let s=t.target;s.closest("openmagic-toolbar")||s.dataset?.openmagic||(o.selectedElement=_e(s),ke(),X(),z.focus())};let e=t=>{t.key==="Escape"&&ke()};document.addEventListener("mousemove",V,!0),document.addEventListener("click",W,!0),document.addEventListener("keydown",e,!0),ae._escHandler=e}function ke(){o.selecting=!1,document.body.style.cursor="",Re(),V&&(document.removeEventListener("mousemove",V,!0),V=null),W&&(document.removeEventListener("click",W,!0),W=null);let e=ae._escHandler;e&&(document.removeEventListener("keydown",e,!0),ae._escHandler=null),J()}async function St(){let e;try{let n=o.selectedElement?.cssSelector?.trim();n&&(e=document.querySelector(n)||void 0)}catch{}let t=await Ae(e||void 0);t.data&&t.data.length>5e3?(o.screenshot=t.data,X(),z.focus()):(o.messages.push({role:"system",content:"Take a screenshot manually (Cmd+Shift+4 on Mac, Win+Shift+S on Windows), then paste it here (Ctrl+V) or drag it onto the prompt bar."}),O("chat"),T())}function Et(){let e=!1,t=0,s=0,n=0,a=0;$.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,s=i.clientY;let d=$.getBoundingClientRect();n=d.left,a=d.top,i.preventDefault()}),document.addEventListener("mousemove",i=>{e&&($.style.left=n+i.clientX-t+"px",$.style.top=a+i.clientY-s+"px",$.style.right="auto",$.style.bottom="auto")}),document.addEventListener("mouseup",()=>{if(e){e=!1;try{localStorage.setItem("__om_pos__",JSON.stringify({left:$.style.left,top:$.style.top}))}catch{}}})}function A(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function $t(e){let t=e.replace(/\\n/g,`
492
- `),s=A(t);return s=s.replace(/```(\w*)\n([\s\S]*?)```/g,'<pre class="om-code-block"><code>$2</code></pre>'),s=s.replace(/`([^`]+)`/g,'<code class="om-inline-code">$1</code>'),s=s.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),s=s.replace(/([^*]|^)\*([^*]+)\*([^*]|$)/g,"$1<em>$2</em>$3"),s=s.replace(/^- (.+)$/gm,"&#8226; $1"),s=s.replace(/\n/g,"<br>"),s}function Lt(){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),s=Ge.split(".").map(Number);for(let n=0;n<3;n++){if((t[n]||0)>(s[n]||0)){o.updateAvailable=!0,o.latestVersion=e.version,Mt();return}if((t[n]||0)<(s[n]||0))return}}).catch(()=>{})}function Mt(){if(w.querySelector(".om-update-dot"))return;let t=document.createElement("span");t.className="om-update-dot",t.title=`v${o.latestVersion} available`,t.addEventListener("click",()=>O("settings"));let s=w.querySelector(".om-toolbar-header");s&&s.appendChild(t)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",je):je());})();
494
+ </div>`).join("")}}var W=null,V=null;function St(){n.selecting?ke():ie()}function ie(){n.selecting=!0,document.body.style.cursor="crosshair",J(),V=t=>{let s=t.target;if(s.closest("openmagic-toolbar")||s.dataset?.openmagic)return;let o=s.getBoundingClientRect();Re({x:o.x,y:o.y,width:o.width,height:o.height})},W=t=>{t.preventDefault(),t.stopPropagation();let s=t.target;s.closest("openmagic-toolbar")||s.dataset?.openmagic||(n.selectedElement=Ne(s),ke(),X(),z.focus())};let e=t=>{t.key==="Escape"&&ke()};document.addEventListener("mousemove",V,!0),document.addEventListener("click",W,!0),document.addEventListener("keydown",e,!0),ie._escHandler=e}function ke(){n.selecting=!1,document.body.style.cursor="",Ae(),V&&(document.removeEventListener("mousemove",V,!0),V=null),W&&(document.removeEventListener("click",W,!0),W=null);let e=ie._escHandler;e&&(document.removeEventListener("keydown",e,!0),ie._escHandler=null),J()}async function $t(){let e;try{let o=n.selectedElement?.cssSelector?.trim();o&&(e=document.querySelector(o)||void 0)}catch{}let t=await Oe(e||void 0);t.data&&t.data.length>5e3?(n.screenshot=t.data,X(),z.focus()):(n.messages.push({role:"system",content:"Take a screenshot manually (Cmd+Shift+4 on Mac, Win+Shift+S on Windows), then paste it here (Ctrl+V) or drag it onto the prompt bar."}),O("chat"),M())}function Et(){let e=!1,t=0,s=0,o=0,r=0;E.addEventListener("mousedown",i=>{let a=i.target;if(a.closest("[data-action]")||!a.closest(".om-grab")&&!a.closest(".om-pill-brand"))return;e=!0,t=i.clientX,s=i.clientY;let c=E.getBoundingClientRect();o=c.left,r=c.top,i.preventDefault()}),document.addEventListener("mousemove",i=>{e&&(E.style.left=o+i.clientX-t+"px",E.style.top=r+i.clientY-s+"px",E.style.right="auto",E.style.bottom="auto")}),document.addEventListener("mouseup",()=>{if(e){e=!1;try{localStorage.setItem("__om_pos__",JSON.stringify({left:E.style.left,top:E.style.top}))}catch{}}})}function A(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function Mt(e){let t=e.replace(/\\n/g,`
495
+ `),s=A(t);return s=s.replace(/```(\w*)\n([\s\S]*?)```/g,'<pre class="om-code-block"><code>$2</code></pre>'),s=s.replace(/`([^`]+)`/g,'<code class="om-inline-code">$1</code>'),s=s.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),s=s.replace(/([^*]|^)\*([^*]+)\*([^*]|$)/g,"$1<em>$2</em>$3"),s=s.replace(/^- (.+)$/gm,"&#8226; $1"),s=s.replace(/\n/g,"<br>"),s}function We(e){let t=[];if(t.push("## Debug Info"),t.push(""),t.push(`- **OpenMagic**: v${Se}`),t.push(`- **Provider**: ${B[n.provider]?.name||n.provider||"not set"}`),t.push(`- **Model**: ${n.model||"not set"}`),t.push(`- **Page URL**: ${window.location.href}`),t.push(`- **Browser**: ${navigator.userAgent}`),n.selectedElement){let a=n.selectedElement,c=a.cssSelector||`${a.tagName}${a.id?"#"+a.id:""}${a.className?"."+a.className.split(" ")[0]:""}`;t.push(`- **Selected Element**: \`${c}\``)}let o=ne().filter(a=>a.level==="error");if(o.length){t.push(""),t.push("### Console Errors"),t.push("```");for(let a of o.slice(-10))t.push(a.args.map(c=>String(c)).join(" ").slice(0,200));t.push("```")}let i=te().filter(a=>a.status&&a.status>=400);if(i.length){t.push(""),t.push("### Failed Requests"),t.push("```");for(let a of i.slice(-10))t.push(`${a.method} ${a.url.slice(0,100)} \u2192 ${a.status}`);t.push("```")}if(e!==void 0){let a=n.messages[e];a&&(t.push(""),t.push("### Message"),t.push("```"),t.push(`[${a.role}] ${a.content.slice(0,1e3)}`),t.push("```"))}else if(n.messages.length){t.push(""),t.push("### Recent Chat"),t.push("```");let a=n.messages.slice(-6);for(let c of a)c.content.startsWith("__DIFF__")||c.content.startsWith("__DIFFGROUP__")||t.push(`[${c.role}] ${c.content.slice(0,300)}`);t.push("```")}return t.join(`
496
+ `)}function Lt(){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),s=Se.split(".").map(Number);for(let o=0;o<3;o++){if((t[o]||0)>(s[o]||0)){n.updateAvailable=!0,n.latestVersion=e.version,Tt();return}if((t[o]||0)<(s[o]||0))return}}).catch(()=>{})}function Tt(){if(w.querySelector(".om-update-dot"))return;let t=document.createElement("span");t.className="om-update-dot",t.title=`v${n.latestVersion} available`,t.addEventListener("click",()=>O("settings"));let s=w.querySelector(".om-toolbar-header");s&&s.appendChild(t)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",Fe):Fe());})();
493
497
  //# sourceMappingURL=index.global.js.map