openmagic 0.9.0 → 0.10.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 +71 -65
- package/dist/cli.js.map +1 -1
- package/dist/toolbar/index.global.js +19 -14
- package/dist/toolbar/index.global.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var OpenMagicToolbar=(()=>{var
|
|
2
|
+
"use strict";var OpenMagicToolbar=(()=>{var B=`
|
|
3
3
|
:host {
|
|
4
4
|
all: initial;
|
|
5
5
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -246,25 +246,25 @@
|
|
|
246
246
|
font-family: 'SF Mono', 'Fira Code', Consolas, monospace;
|
|
247
247
|
font-size: 10px; color: #555; max-height: 60px; overflow-y: auto; margin-bottom: 6px;
|
|
248
248
|
}
|
|
249
|
-
`;var p=null,m=new Map,
|
|
250
|
-
`);n=`<${
|
|
249
|
+
`;var p=null,m=new Map,ge=[],N=[],y=!1,U=!1,P=null;function _(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function O(e,t){return U=!0,new Promise((o,n)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,n(new Error("Handshake timeout")),p?.close())},1e4);try{p=new WebSocket(`ws://127.0.0.1:${e}/__openmagic__/ws`),p.onopen=()=>{let r=_();p.send(JSON.stringify({id:r,type:"handshake",payload:{token:t}})),m.set(r,l=>{if(l.type==="handshake.ok"){clearTimeout(i),y=!0;for(let f of N)p?.send(f);N=[],s||(s=!0,o())}else l.type==="error"&&(clearTimeout(i),s||(s=!0,n(new Error(l.payload?.message||"Handshake failed"))))})},p.onmessage=r=>{try{let l=JSON.parse(r.data);l.id&&m.has(l.id)&&(m.get(l.id)(l),(l.type==="llm.done"||l.type==="llm.error"||!l.type.startsWith("llm."))&&m.delete(l.id));for(let f of ge)f(l)}catch{}},p.onclose=()=>{let r=y;if(y=!1,!r&&!s){clearTimeout(i),s=!0,n(new Error("WebSocket closed before handshake"));return}r&&U&&!P&&(P=setTimeout(()=>{P=null,O(e,t).catch(()=>{})},2e3))},p.onerror=()=>{!y&&!s&&(clearTimeout(i),s=!0,n(new Error("WebSocket connection failed")))}}catch(r){clearTimeout(i),s||(s=!0,n(r))}})}function z(e){let t=JSON.stringify(e);p&&p.readyState===WebSocket.OPEN&&y?p.send(t):N.push(t)}function k(e,t){return new Promise((o,n)=>{let s=_(),i=setTimeout(()=>{m.delete(s),n(new Error("Request timeout"))},3e4);m.set(s,r=>{clearTimeout(i),r.type==="error"?n(new Error(r.payload?.message||"Unknown error")):o(r)}),z({id:s,type:e,payload:t})})}function G(e,t,o){return new Promise((n,s)=>{let i=_(),r=setTimeout(()=>{m.delete(i),s(new Error("Stream timeout"))},12e4);m.set(i,l=>{l.type==="llm.chunk"?o(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(r),m.delete(i),n(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(r),m.delete(i),s(new Error(l.payload?.message||"Stream error")))}),z({id:i,type:e,payload:t})})}function I(){return y}var fe=["display","position","width","height","margin","padding","color","background-color","background","font-size","font-weight","font-family","border","border-radius","box-shadow","flex-direction","justify-content","align-items","gap","grid-template-columns","grid-template-rows","overflow","opacity","z-index","text-align","line-height","letter-spacing"];function K(e){let t=window.getComputedStyle(e),o={};for(let s of fe)o[s]=t.getPropertyValue(s);let n=e.getBoundingClientRect();return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().slice(0,200),outerHTML:be(e),cssSelector:ye(e),xpath:xe(e),computedStyles:o,rect:{x:n.x,y:n.y,width:n.width,height:n.height}}}function be(e){let t=e.cloneNode(!0);t.querySelectorAll("script, style, svg").forEach(s=>s.remove());let n=t.outerHTML;if(n.length>2e3){let s=e.tagName.toLowerCase(),i=Array.from(e.attributes).map(l=>`${l.name}="${l.value}"`).join(" "),r=Array.from(e.children).slice(0,5).map(l=>`<${l.tagName.toLowerCase()} .../>`).join(`
|
|
250
|
+
`);n=`<${s} ${i}>
|
|
251
251
|
${r}
|
|
252
252
|
${e.children.length>5?`<!-- +${e.children.length-5} more children -->`:""}
|
|
253
|
-
</${
|
|
253
|
+
</${s}>`}return n}function ye(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=[],o=e;for(;o&&o!==document.body;){let n=o.tagName.toLowerCase();if(o.id){t.unshift(`#${CSS.escape(o.id)}`);break}if(o.className&&typeof o.className=="string"){let i=o.className.trim().split(/\s+/).filter(r=>!r.startsWith("__")&&r.length<30).slice(0,2).map(r=>CSS.escape(r));i.length>0&&(n+="."+i.join("."))}let s=o.parentElement;if(s){let i=Array.from(s.children).filter(r=>r.tagName===o.tagName);if(i.length>1){let r=i.indexOf(o)+1;n+=`:nth-of-type(${r})`}}t.unshift(n),o=o.parentElement}return t.join(" > ")}function xe(e){let t=[],o=e;for(;o&&o!==document;){if(o.nodeType===Node.ELEMENT_NODE){let n=o,s=1,i=n.previousElementSibling;for(;i;)i.tagName===n.tagName&&s++,i=i.previousElementSibling;t.unshift(`${n.tagName.toLowerCase()}[${s}]`)}o=o.parentNode}return"/"+t.join("/")}var d=null;function j(e){d||(d=document.createElement("div"),d.style.cssText=`
|
|
254
254
|
position: fixed;
|
|
255
255
|
pointer-events: none;
|
|
256
256
|
z-index: 2147483646;
|
|
257
257
|
border: 2px solid #6c5ce7;
|
|
258
258
|
background: rgba(108, 92, 231, 0.1);
|
|
259
259
|
transition: all 0.1s ease;
|
|
260
|
-
`,d.dataset.openmagic="highlight",document.body.appendChild(d)),d.style.left=`${e.x}px`,d.style.top=`${e.y}px`,d.style.width=`${e.width}px`,d.style.height=`${e.height}px`,d.style.display="block"}function
|
|
261
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="${
|
|
260
|
+
`,d.dataset.openmagic="highlight",document.body.appendChild(d)),d.style.left=`${e.x}px`,d.style.top=`${e.y}px`,d.style.width=`${e.width}px`,d.style.height=`${e.height}px`,d.style.display="block"}function V(){d&&(d.style.display="none")}async function F(e){try{return e?await we(e):await ve()}catch(t){return console.warn("[OpenMagic] Screenshot capture failed:",t),null}}async function ve(){let e=document.createElement("canvas"),t=window.devicePixelRatio||1;e.width=window.innerWidth*t,e.height=window.innerHeight*t;let o=e.getContext("2d");o.scale(t,t);try{let n=await W(document.body),s=await Y(n,window.innerWidth,window.innerHeight);return o.drawImage(s,0,0),e.toDataURL("image/png")}catch{return null}}async function we(e){let t=e.getBoundingClientRect(),o=document.createElement("canvas"),n=window.devicePixelRatio||1;o.width=t.width*n,o.height=t.height*n;let s=o.getContext("2d");s.scale(n,n);try{let i=await W(e),r=await Y(i,t.width,t.height);return s.drawImage(r,0,0),o.toDataURL("image/png")}catch{return null}}function W(e){return new Promise(t=>{let o=e.cloneNode(!0);X(e,o);let n=e.getBoundingClientRect(),s=n.width,i=n.height,r=`
|
|
261
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${i}">
|
|
262
262
|
<foreignObject width="100%" height="100%">
|
|
263
|
-
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${
|
|
263
|
+
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${s}px;height:${i}px;overflow:hidden;">
|
|
264
264
|
${o.outerHTML}
|
|
265
265
|
</div>
|
|
266
266
|
</foreignObject>
|
|
267
|
-
</svg>`;t(r)})}function
|
|
267
|
+
</svg>`;t(r)})}function X(e,t){let o=window.getComputedStyle(e),n="";for(let r=0;r<o.length;r++){let l=o[r];n+=`${l}:${o.getPropertyValue(l)};`}t.style.cssText=n;let s=e.children,i=t.children;for(let r=0;r<s.length&&r<i.length;r++)X(s[r],i[r])}function Y(e,t,o){return new Promise((n,s)=>{let i=new Image,r=new Blob([e],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(r);i.onload=()=>{URL.revokeObjectURL(l),n(i)},i.onerror=()=>{URL.revokeObjectURL(l),s(new Error("Failed to load SVG image"))},i.width=t,i.height=o,i.src=l})}var E=[];var J=!1;function Z(){if(J)return;J=!0;let e=window.fetch;window.fetch=async function(...n){let s=new Request(...n),i={method:s.method,url:s.url,timestamp:Date.now()};try{let r=await e.apply(this,n);return i.status=r.status,i.duration=Date.now()-i.timestamp,R(i),r}catch(r){throw i.status=0,i.duration=Date.now()-i.timestamp,R(i),r}};let t=XMLHttpRequest.prototype.open,o=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(n,s,...i){return this.__om_method=n,this.__om_url=s,this.__om_start=Date.now(),t.apply(this,[n,s,...i])},XMLHttpRequest.prototype.send=function(...n){return this.addEventListener("loadend",()=>{R({method:this.__om_method||"GET",url:this.__om_url||"",status:this.status,duration:Date.now()-(this.__om_start||Date.now()),timestamp:this.__om_start||Date.now()})}),o.apply(this,n)}}function R(e){e.url.includes("__openmagic__")||(E.push(e),E.length>50&&E.shift())}function ke(){return[...E]}var T=[],Se=100,Q=!1;function ee(){if(Q)return;Q=!0;let e=["log","warn","error","info","debug"];for(let t of e){let o=console[t];console[t]=function(...n){T.push({level:t,args:n.map(s=>{try{return typeof s=="object"?JSON.stringify(s).slice(0,500):String(s)}catch{return String(s)}}),timestamp:Date.now()}),T.length>Se&&T.shift(),o.apply(console,n)}}}function Le(){return[...T]}function te(e,t){return{selectedElement:e?{tagName:e.tagName,id:e.id,className:e.className,textContent:e.textContent,outerHTML:e.outerHTML,cssSelector:e.cssSelector,computedStyles:e.computedStyles}:void 0,screenshot:t||void 0,networkLogs:ke().map(o=>({method:o.method,url:o.url,status:o.status,duration:o.duration,timestamp:o.timestamp})),consoleLogs:Le().map(o=>({level:o.level,args:o.args,timestamp:o.timestamp}))}}var c={sparkle:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.582a.5.5 0 0 1 0 .962L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/></svg>',crosshair:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="22" y1="12" x2="18" y2="12"/><line x1="6" y1="12" x2="2" y2="12"/><line x1="12" y1="6" x2="12" y2="2"/><line x1="12" y1="22" x2="12" y2="18"/></svg>',camera:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></svg>',chat:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',settings:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>',send:'<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>',x:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',externalLink:'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>',check:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg>',grip:'<svg width="7" height="14" viewBox="0 0 8 14" fill="currentColor"><circle cx="2" cy="2" r="1.2"/><circle cx="6" cy="2" r="1.2"/><circle cx="2" cy="7" r="1.2"/><circle cx="6" cy="7" r="1.2"/><circle cx="2" cy="12" r="1.2"/><circle cx="6" cy="12" r="1.2"/></svg>'},H={openai:{name:"OpenAI",keyUrl:"https://platform.openai.com/api-keys",keyPlaceholder:"sk-...",models:[{id:"gpt-5.4",name:"GPT-5.4"},{id:"gpt-5.4-mini",name:"GPT-5.4 Mini"},{id:"gpt-5.2",name:"GPT-5.2 Thinking"},{id:"o3",name:"o3"},{id:"o4-mini",name:"o4-mini"},{id:"gpt-4.1",name:"GPT-4.1"},{id:"gpt-4.1-mini",name:"GPT-4.1 Mini"}]},anthropic:{name:"Anthropic",keyUrl:"https://console.anthropic.com/settings/keys",keyPlaceholder:"sk-ant-...",models:[{id:"claude-opus-4-6",name:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",name:"Claude Sonnet 4.6"},{id:"claude-haiku-4-5-20251001",name:"Claude Haiku 4.5"}]},google:{name:"Google Gemini",keyUrl:"https://aistudio.google.com/apikey",keyPlaceholder:"AIza...",models:[{id:"gemini-3.1-pro-preview",name:"Gemini 3.1 Pro"},{id:"gemini-3-flash-preview",name:"Gemini 3 Flash"},{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro"},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash"}]},xai:{name:"xAI (Grok)",keyUrl:"https://console.x.ai/team/default/api-keys",keyPlaceholder:"xai-...",models:[{id:"grok-4.20-0309-reasoning",name:"Grok 4.20 Reasoning"},{id:"grok-4-1-fast-non-reasoning",name:"Grok 4.1 Fast"}]},deepseek:{name:"DeepSeek",keyUrl:"https://platform.deepseek.com/api_keys",keyPlaceholder:"sk-...",models:[{id:"deepseek-chat",name:"DeepSeek V3.2"},{id:"deepseek-reasoner",name:"DeepSeek R1"}]},mistral:{name:"Mistral",keyUrl:"https://console.mistral.ai/api-keys",keyPlaceholder:"...",models:[{id:"mistral-large-3-25-12",name:"Mistral Large 3"},{id:"codestral-2508",name:"Codestral"},{id:"devstral-2-25-12",name:"Devstral 2"}]},groq:{name:"Groq",keyUrl:"https://console.groq.com/keys",keyPlaceholder:"gsk_...",models:[{id:"meta-llama/llama-4-scout-17b-16e-instruct",name:"Llama 4 Scout"},{id:"llama-3.3-70b-versatile",name:"Llama 3.3 70B"}]},minimax:{name:"MiniMax",keyUrl:"https://platform.minimax.chat/user-center/basic-information/interface-key",keyPlaceholder:"MiniMax key...",models:[{id:"MiniMax-M2.7",name:"MiniMax M2.7"},{id:"MiniMax-M2.5",name:"MiniMax M2.5"}]},moonshot:{name:"Kimi (Moonshot)",keyUrl:"https://platform.moonshot.cn/console/api-keys",keyPlaceholder:"Moonshot key...",models:[{id:"kimi-k2.5",name:"Kimi K2.5"},{id:"kimi-k2-thinking",name:"Kimi K2 Thinking"}]},qwen:{name:"Qwen (Alibaba)",keyUrl:"https://dashscope.console.aliyun.com/apiKey",keyPlaceholder:"DashScope key...",models:[{id:"qwen3.5-plus",name:"Qwen 3.5 Plus"},{id:"qwen-max",name:"Qwen Max"}]},zhipu:{name:"Zhipu AI (GLM)",keyUrl:"https://open.bigmodel.cn/usercenter/apikeys",keyPlaceholder:"Zhipu key...",models:[{id:"glm-5",name:"GLM-5"},{id:"glm-4.7",name:"GLM-4.7"}]},doubao:{name:"Doubao (ByteDance)",keyUrl:"https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey",keyPlaceholder:"Volcano key...",models:[{id:"doubao-seed-2-0-pro",name:"Doubao Seed 2.0 Pro"},{id:"doubao-seed-2-0-code",name:"Doubao Seed 2.0 Code"}]},ollama:{name:"Ollama (Local)",keyPlaceholder:"not required",local:!0,models:[]},openrouter:{name:"OpenRouter",keyUrl:"https://openrouter.ai/settings/keys",keyPlaceholder:"sk-or-...",models:[]}},ie="0.10.0",a={connected:!1,panelOpen:!1,activePanel:"",selecting:!1,selectedElement:null,screenshot:null,messages:[],streaming:!1,streamContent:"",provider:"",model:"",hasApiKey:!1,roots:[],updateAvailable:!1,latestVersion:"",saveStatus:""},g,h,v,re,q,u;function oe(){if(document.querySelector("openmagic-toolbar"))return;let e=document.createElement("openmagic-toolbar");e.dataset.openmagic="true",g=e.attachShadow({mode:"closed"});let t=document.createElement("style");t.textContent=B,g.appendChild(t);let o=document.createElement("div");g.appendChild(o),o.innerHTML=Me(),h=o.querySelector(".om-toolbar"),v=o.querySelector(".om-prompt-input"),re=o.querySelector(".om-prompt-context"),q=o.querySelector(".om-panel"),u=o.querySelector(".om-panel-body"),document.body.appendChild(e),Ee(o),Oe(),Z(),ee(),Re();let n=window.__OPENMAGIC_CONFIG__;n&&O(n.wsPort,n.token).then(()=>(a.connected=!0,ne(),k("config.get"))).then(s=>{a.provider=s.payload?.provider||"",a.model=s.payload?.model||"",a.hasApiKey=s.payload?.hasApiKey||!1,a.roots=s.payload?.roots||[],(!a.provider||!a.hasApiKey)&&w("settings"),M()}).catch(()=>{a.connected=!1,ne()})}function Me(){return`
|
|
268
268
|
<div class="om-toolbar">
|
|
269
269
|
<div class="om-toolbar-header">
|
|
270
270
|
<span class="om-grab">${c.grip}</span>
|
|
@@ -281,6 +281,11 @@
|
|
|
281
281
|
<span class="om-status-dot disconnected"></span>
|
|
282
282
|
</div>
|
|
283
283
|
<div class="om-panel om-hidden">
|
|
284
|
+
<div class="om-panel-header">
|
|
285
|
+
<span class="om-panel-title"></span>
|
|
286
|
+
<span class="om-panel-version">v${ie}</span>
|
|
287
|
+
<button class="om-panel-close" data-action="close-panel">${c.x}</button>
|
|
288
|
+
</div>
|
|
284
289
|
<div class="om-panel-body"></div>
|
|
285
290
|
</div>
|
|
286
291
|
<div class="om-prompt-row">
|
|
@@ -288,7 +293,7 @@
|
|
|
288
293
|
<input class="om-prompt-input" type="text" placeholder="Describe what to change..." autocomplete="off" />
|
|
289
294
|
<button class="om-prompt-send" data-action="prompt-send">${c.send}</button>
|
|
290
295
|
</div>
|
|
291
|
-
</div>`}function
|
|
296
|
+
</div>`}function Ee(e){e.addEventListener("click",t=>{let o=t.target.closest("[data-action]");if(!o)return;t.preventDefault(),t.stopPropagation();let n=o.dataset.action;Te(n,o)}),e.addEventListener("change",t=>{let o=t.target,n=o.dataset.field;n&&(n==="provider"?(a.provider=o.value,a.model="",a.saveStatus="",x()):n==="model"&&(a.model=o.value))}),v.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),ce())})}function Te(e,t){switch(e){case"select":Pe();break;case"screenshot":_e();break;case"chat":ae("chat");break;case"settings":ae("settings");break;case"close-panel":le();break;case"prompt-send":ce();break;case"save-settings":$e();break;case"get-key":{let o=t.dataset.url;o&&window.open(o,"_blank","noopener");break}case"clear-element":a.selectedElement=null,$();break;case"clear-screenshot":a.screenshot=null,$();break}}function ne(){let e=g.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${a.connected?"connected":"disconnected"}`)}function M(){g.querySelectorAll(".om-pill-btn").forEach(e=>{let t=e.dataset.action;e.classList.toggle("active",t===a.activePanel||t==="select"&&a.selecting)})}function $(){let e=[];a.selectedElement&&e.push(`<span class="om-prompt-chip">${a.selectedElement.tagName}${a.selectedElement.id?"#"+a.selectedElement.id:""} <button class="om-prompt-chip-x" data-action="clear-element">${c.x}</button></span>`),a.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${c.x}</button></span>`),re.innerHTML=e.join("")}function w(e){a.panelOpen=!0,a.activePanel=e,q.classList.remove("om-hidden");let t=g.querySelector(".om-panel-title");t&&(t.textContent=e==="settings"?"Settings":"Chat"),x(),M()}function le(){a.panelOpen=!1,a.activePanel="",q.classList.add("om-hidden"),M()}function ae(e){a.panelOpen&&a.activePanel===e?le():w(e)}function x(){a.activePanel==="settings"?u.innerHTML=Ce():a.activePanel==="chat"&&(u.innerHTML=He(),A())}function Ce(){let e=Object.entries(H).map(([b,ue])=>`<option value="${b}" ${a.provider===b?"selected":""}>${ue.name}</option>`).join(""),t=H[a.provider],o=t?t.models.map(b=>`<option value="${b.id}" ${a.model===b.id?"selected":""}>${b.name}</option>`).join(""):'<option value="">Select provider first</option>',n=t?.local||!1,s=t?.keyUrl||"",i=t?.keyPlaceholder||"Enter API key...",r=a.updateAvailable?`<div class="om-update-banner">v${a.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",l=a.hasApiKey?`<div class="om-status om-status-success">${c.check} Connected</div>`:"",f=a.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':a.saveStatus==="saved"?`${c.check} Saved`:"Save",pe=a.saveStatus==="saving"?"om-btn om-btn-saving":a.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",me=a.saveStatus==="saving"?"disabled":"";return`
|
|
292
297
|
${r}
|
|
293
298
|
<div class="om-settings">
|
|
294
299
|
<div class="om-field">
|
|
@@ -302,12 +307,12 @@
|
|
|
302
307
|
<div class="om-field ${n?"om-hidden":""}">
|
|
303
308
|
<label class="om-label">API Key</label>
|
|
304
309
|
<div class="om-key-row">
|
|
305
|
-
<input type="text" class="om-input om-key-input" data-field="apiKey" placeholder="${
|
|
306
|
-
${
|
|
310
|
+
<input type="text" class="om-input om-key-input" data-field="apiKey" placeholder="${i}" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
|
|
311
|
+
${s?`<button class="om-btn-get-key" data-action="get-key" data-url="${s}">${c.externalLink} Get key</button>`:""}
|
|
307
312
|
</div>
|
|
308
|
-
${
|
|
313
|
+
${s?`<div class="om-key-hint"><a data-action="get-key" data-url="${s}">Get your ${t?.name||""} API key here</a></div>`:""}
|
|
309
314
|
</div>
|
|
310
|
-
<button class="${
|
|
315
|
+
<button class="${pe}" data-action="save-settings" ${me}>${f}</button>
|
|
311
316
|
${l}
|
|
312
|
-
</div>`}function
|
|
317
|
+
</div>`}function He(){if(!a.provider||!a.hasApiKey&&!H[a.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=a.messages.map(n=>`<div class="om-msg om-msg-${n.role}">${D(n.content)}</div>`).join(""),t=a.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${D(a.streamContent)}</div>`:"";return`<div class="om-chat-messages">${!a.messages.length&&!a.streaming?'<div class="om-chat-empty">Select an element or type below to start</div>':""}${e}${t}</div>`}function A(){requestAnimationFrame(()=>{let e=u.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function $e(){let t=u.querySelector('[data-field="apiKey"]')?.value||"";if(!a.provider){a.saveStatus="error",C(),setTimeout(()=>{a.saveStatus="",x()},2e3);return}if(!I()){a.saveStatus="error",C();let n=u.querySelector('[data-action="save-settings"]');n&&(n.innerHTML="Not connected - check terminal"),setTimeout(()=>{a.saveStatus="",x()},3e3);return}let o={provider:a.provider,model:a.model};t&&(o.apiKey=t),a.saveStatus="saving",C();try{let n=await Promise.race([k("config.set",o),new Promise((s,i)=>setTimeout(()=>i(new Error("Save timed out")),8e3))]);a.hasApiKey=!!(t||a.hasApiKey),a.saveStatus="saved",C(),setTimeout(()=>{a.saveStatus="",a.activePanel==="settings"&&w("chat")},1200)}catch(n){a.saveStatus="error";let s=u.querySelector('[data-action="save-settings"]'),i=(n?.message||"").includes("timeout")?"Connection timeout - is the CLI running?":(n?.message||"").includes("connected")?"Not connected to OpenMagic server":`Save failed: ${n?.message||"Unknown error"}`;s&&(s.innerHTML=i,s.className="om-btn",s.disabled=!1),setTimeout(()=>{a.saveStatus="",x()},4e3)}}function C(){let e=u.querySelector('[data-action="save-settings"]');e&&(a.saveStatus==="saving"?(e.innerHTML='<span class="om-spinner"></span> Saving...',e.className="om-btn om-btn-saving",e.disabled=!0):a.saveStatus==="saved"?(e.innerHTML=`${c.check} Saved`,e.className="om-btn om-btn-saved",e.disabled=!1):a.saveStatus==="error"?(e.innerHTML="Save failed - try again",e.className="om-btn",e.disabled=!1):(e.innerHTML="Save",e.className="om-btn",e.disabled=!1))}async function ce(){let e=v.value.trim();if(!e||a.streaming)return;if(!a.provider||!a.hasApiKey&&!H[a.provider]?.local){w("settings");return}a.messages.push({role:"user",content:e}),a.streaming=!0,a.streamContent="",v.value="",w("chat");let t=te(a.selectedElement,a.screenshot);t.pageUrl=window.location.href,t.pageTitle=document.title;try{let o=await G("llm.chat",{provider:a.provider,model:a.model,messages:a.messages.map(n=>({role:n.role,content:n.content})),context:t},n=>{a.streamContent+=n;let s=u.querySelector(".om-msg-assistant:last-child");s&&(s.innerHTML=`<span class="om-spinner"></span>${D(a.streamContent)}`,A())});if(a.messages.push({role:"assistant",content:a.streamContent||o?.content||""}),o?.modifications?.length){for(let n of o.modifications)if(n.type==="edit"&&n.file&&n.search&&n.replace)try{let i=(await k("fs.read",{path:se(n.file)})).payload?.content;if(i?.includes(n.search)){let r=await k("fs.write",{path:se(n.file),content:i.replace(n.search,n.replace)});r?.payload?.ok===!1?a.messages.push({role:"system",content:`Write failed: ${n.file} - ${r.payload.error||"unknown"}`}):a.messages.push({role:"system",content:`Applied change to ${n.file}`})}}catch(s){a.messages.push({role:"system",content:`Failed: ${n.file} - ${s.message}`})}}}catch(o){a.messages.push({role:"system",content:`Error: ${o.message}`})}a.streaming=!1,a.streamContent="",x(),A()}function se(e){return a.roots.length>0?a.roots[0]+"/"+e:e}var S=null,L=null;function Pe(){a.selecting?de():Ne()}function Ne(){a.selecting=!0,document.body.style.cursor="crosshair",M(),L=e=>{let t=e.target;if(t.closest("openmagic-toolbar")||t.dataset?.openmagic)return;let o=t.getBoundingClientRect();j({x:o.x,y:o.y,width:o.width,height:o.height})},S=e=>{e.preventDefault(),e.stopPropagation();let t=e.target;t.closest("openmagic-toolbar")||t.dataset?.openmagic||(a.selectedElement=K(t),de(),$(),v.focus())},document.addEventListener("mousemove",L,!0),document.addEventListener("click",S,!0)}function de(){a.selecting=!1,document.body.style.cursor="",V(),L&&(document.removeEventListener("mousemove",L,!0),L=null),S&&(document.removeEventListener("click",S,!0),S=null),M()}async function _e(){let e=await F();e&&(a.screenshot=e,$(),v.focus())}function Oe(){let e=!1,t=0,o=0,n=0,s=0;h.addEventListener("mousedown",i=>{let r=i.target;if(r.closest("[data-action]")||!r.closest(".om-grab")&&!r.closest(".om-pill-brand"))return;e=!0,t=i.clientX,o=i.clientY;let l=h.getBoundingClientRect();n=l.left,s=l.top,i.preventDefault()}),document.addEventListener("mousemove",i=>{e&&(h.style.left=n+i.clientX-t+"px",h.style.top=s+i.clientY-o+"px",h.style.right="auto",h.style.bottom="auto")}),document.addEventListener("mouseup",()=>{e=!1})}function D(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function Re(){fetch("https://registry.npmjs.org/openmagic/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(5e3)}).then(e=>e.ok?e.json():null).then(e=>{if(!e?.version)return;let t=e.version.split(".").map(Number),o=ie.split(".").map(Number);for(let n=0;n<3;n++){if((t[n]||0)>(o[n]||0)){a.updateAvailable=!0,a.latestVersion=e.version,Ae();return}if((t[n]||0)<(o[n]||0))return}}).catch(()=>{})}function Ae(){if(g.querySelector(".om-update-dot"))return;let t=document.createElement("span");t.className="om-update-dot",t.title=`v${a.latestVersion} available`,t.addEventListener("click",()=>w("settings"));let o=g.querySelector(".om-toolbar-header");o&&o.appendChild(t)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",oe):oe());})();
|
|
313
318
|
//# sourceMappingURL=index.global.js.map
|