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