openmagic 0.13.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/cli.js +34 -69
- package/dist/cli.js.map +1 -1
- package/dist/toolbar/index.global.js +19 -19
- 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 Z=`
|
|
3
3
|
:host {
|
|
4
4
|
all: initial;
|
|
5
5
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -275,54 +275,54 @@
|
|
|
275
275
|
.om-btn-secondary:hover { background: rgba(255,255,255,0.08); color: #ccc; }
|
|
276
276
|
.om-diff-applied { opacity: 0.5; }
|
|
277
277
|
.om-diff-applied .om-diff-actions { display: none; }
|
|
278
|
-
`;var
|
|
278
|
+
`;var b=null,f=new Map,C=[],j=[],M=!1,ee=!1,z=null,U=0;function G(){return Math.random().toString(36).slice(2)+Date.now().toString(36)}function K(e,t){return ee=!0,new Promise((o,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=G();b.send(JSON.stringify({id:d,type:"handshake",payload:{token:t}})),f.set(d,c=>{if(c.type==="handshake.ok"){clearTimeout(s),M=!0,U=0;for(let p of j)b?.send(p);j=[],r||(r=!0,o())}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&&f.has(c.id)&&(f.get(c.id)(c),(c.type==="llm.done"||c.type==="llm.error"||!c.type.startsWith("llm."))&&f.delete(c.id));for(let p of C)p(c)}catch{}},b.onclose=()=>{let d=M;if(M=!1,f.forEach((c,p)=>{c({type:"error",id:p,payload:{message:"Connection lost"}})}),f.clear(),!d&&!r){clearTimeout(s),r=!0,a(new Error("WebSocket closed before handshake"));return}if(d&&ee&&!z){let c=Math.min(2e3*Math.pow(1.5,U),3e4);U++,z=setTimeout(()=>{z=null,K(e,t).then(()=>{for(let p of C)p({type:"reconnected",payload:{}})}).catch(()=>{})},c)}},b.onerror=()=>{!M&&!r&&(clearTimeout(s),r=!0,a(new Error("WebSocket connection failed")))}}catch(i){clearTimeout(s),r||(r=!0,a(i))}})}function te(e){let t=JSON.stringify(e);b&&b.readyState===WebSocket.OPEN&&M?b.send(t):j.push(t)}function S(e,t){return new Promise((o,a)=>{let r=G(),s=setTimeout(()=>{f.delete(r),a(new Error("Request timeout"))},3e4);f.set(r,i=>{clearTimeout(s),i.type==="error"?a(new Error(i.payload?.message||"Unknown error")):o(i)}),te({id:r,type:e,payload:t})})}function oe(e,t,o){return new Promise((a,r)=>{let s=G(),i=setTimeout(()=>{f.delete(s),r(new Error("Stream timeout"))},12e4);f.set(s,l=>{l.type==="llm.chunk"?o(l.payload?.delta||""):l.type==="llm.done"?(clearTimeout(i),f.delete(s),a(l.payload)):(l.type==="llm.error"||l.type==="error")&&(clearTimeout(i),f.delete(s),r(new Error(l.payload?.message||"Stream error")))}),te({id:s,type:e,payload:t})})}function ne(e){return C.push(e),()=>{C=C.filter(t=>t!==e)}}function ae(){return M}var Me=["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 t=window.getComputedStyle(e),o={};for(let r of Me)o[r]=t.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:Le(e),cssSelector:Te(e),xpath:Ce(e),computedStyles:o,rect:{x:a.x,y:a.y,width:a.width,height:a.height}}}function Le(e){let t=e.cloneNode(!0);t.querySelectorAll("script, style, svg").forEach(r=>r.remove());let a=t.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
279
|
`);a=`<${r} ${s}>
|
|
280
280
|
${i}
|
|
281
281
|
${e.children.length>5?`<!-- +${e.children.length-5} more children -->`:""}
|
|
282
|
-
</${r}>`}return a}function
|
|
282
|
+
</${r}>`}return a}function Te(e){if(e.id)return`#${CSS.escape(e.id)}`;let t=[],o=e;for(;o&&o!==document.body;){let a=o.tagName.toLowerCase();if(o.id){t.unshift(`#${CSS.escape(o.id)}`);break}if(o.className&&typeof o.className=="string"){let s=o.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=o.parentElement;if(r){let s=Array.from(r.children).filter(i=>i.tagName===o.tagName);if(s.length>1){let i=s.indexOf(o)+1;a+=`:nth-of-type(${i})`}}t.unshift(a),o=o.parentElement}return t.join(" > ")}function Ce(e){let t=[],o=e;for(;o&&o!==document;){if(o.nodeType===Node.ELEMENT_NODE){let a=o,r=1,s=a.previousElementSibling;for(;s;)s.tagName===a.tagName&&r++,s=s.previousElementSibling;t.unshift(`${a.tagName.toLowerCase()}[${r}]`)}o=o.parentNode}return"/"+t.join("/")}var y=null;function re(e){y||(y=document.createElement("div"),y.style.cssText=`
|
|
283
283
|
position: fixed;
|
|
284
284
|
pointer-events: none;
|
|
285
285
|
z-index: 2147483646;
|
|
286
286
|
border: 2px solid #6c5ce7;
|
|
287
287
|
background: rgba(108, 92, 231, 0.1);
|
|
288
288
|
transition: all 0.1s ease;
|
|
289
|
-
`,
|
|
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 He(e):await $e()}catch(t){return console.warn("[OpenMagic] Screenshot capture failed:",t),null}}async function $e(){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 a=await ce(document.body),r=await pe(a,window.innerWidth,window.innerHeight);return o.drawImage(r,0,0),e.toDataURL("image/png")}catch{return null}}async function He(e){let t=e.getBoundingClientRect(),o=document.createElement("canvas"),a=window.devicePixelRatio||1;o.width=t.width*a,o.height=t.height*a;let r=o.getContext("2d");r.scale(a,a);try{let s=await ce(e),i=await pe(s,t.width,t.height);return r.drawImage(i,0,0),o.toDataURL("image/png")}catch{return null}}function ce(e){return new Promise(t=>{let o=e.cloneNode(!0);de(e,o);let a=e.getBoundingClientRect(),r=a.width,s=a.height,i=`
|
|
290
290
|
<svg xmlns="http://www.w3.org/2000/svg" width="${r}" height="${s}">
|
|
291
291
|
<foreignObject width="100%" height="100%">
|
|
292
292
|
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${r}px;height:${s}px;overflow:hidden;">
|
|
293
293
|
${o.outerHTML}
|
|
294
294
|
</div>
|
|
295
295
|
</foreignObject>
|
|
296
|
-
</svg>`;t(i)})}function
|
|
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.1",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`
|
|
297
297
|
<div class="om-toolbar">
|
|
298
298
|
<div class="om-toolbar-header">
|
|
299
|
-
<span class="om-grab">${
|
|
299
|
+
<span class="om-grab">${u.grip}</span>
|
|
300
300
|
<span class="om-pill-brand">
|
|
301
|
-
<span class="om-pill-icon">${
|
|
301
|
+
<span class="om-pill-icon">${u.sparkle}</span>
|
|
302
302
|
<span class="om-pill-text">OpenMagic</span>
|
|
303
303
|
</span>
|
|
304
304
|
<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">${
|
|
305
|
+
<button class="om-pill-btn" data-action="select" title="Select element">${u.crosshair}</button>
|
|
306
|
+
<button class="om-pill-btn" data-action="screenshot" title="Screenshot">${u.camera}</button>
|
|
307
307
|
<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">${
|
|
308
|
+
<button class="om-pill-btn" data-action="chat" title="Chat">${u.chat}</button>
|
|
309
|
+
<button class="om-pill-btn" data-action="settings" title="Settings">${u.settings}</button>
|
|
310
310
|
<span class="om-status-dot disconnected"></span>
|
|
311
311
|
</div>
|
|
312
312
|
<div class="om-panel om-hidden">
|
|
313
313
|
<div class="om-panel-header">
|
|
314
314
|
<span class="om-panel-title"></span>
|
|
315
|
-
<span class="om-panel-version">v${
|
|
316
|
-
<button class="om-panel-close" data-action="close-panel">${
|
|
315
|
+
<span class="om-panel-version">v${ve}</span>
|
|
316
|
+
<button class="om-panel-close" data-action="close-panel">${u.x}</button>
|
|
317
317
|
</div>
|
|
318
318
|
<div class="om-panel-body"></div>
|
|
319
319
|
</div>
|
|
320
320
|
<div class="om-prompt-row">
|
|
321
321
|
<div class="om-prompt-context"></div>
|
|
322
322
|
<input class="om-prompt-input" type="text" placeholder="Describe what to change..." autocomplete="off" />
|
|
323
|
-
<button class="om-prompt-send" data-action="prompt-send">${
|
|
323
|
+
<button class="om-prompt-send" data-action="prompt-send">${u.send}</button>
|
|
324
324
|
</div>
|
|
325
|
-
</div>`}function
|
|
325
|
+
</div>`}function Re(e){e.addEventListener("click",t=>{let o=t.target.closest("[data-action]");if(!o)return;t.preventDefault(),t.stopPropagation();let a=o.dataset.action;qe(a,o)}),e.addEventListener("change",t=>{let o=t.target,a=o.dataset.field;a&&(a==="provider"?(n.provider=o.value,n.model=_[n.provider]?.models[0]?.id||"",n.saveStatus="",k()):a==="model"&&(n.model=o.value))}),L.addEventListener("keydown",t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),Se())}),ne(t=>{t.type==="reconnected"&&(n.connected=!0,W())})}function be(e){return n.roots.length>0?n.roots[0]+"/"+e:e}async function Ae(e){let t=e.dataset.file,o=e.dataset.search,a=e.dataset.replace;if(!t||!o||!a)return;let r=X(o),s=X(a),i=e.closest(".om-diff-card");try{let d=(await S("fs.read",{path:be(t)})).payload?.content,c=d?d.split(r).length-1:0;if(c===0)n.messages.push({role:"system",content:`Could not find matching code in ${t}`});else if(c>1)n.messages.push({role:"system",content:`Found ${c} matches in ${t} \u2014 expected exactly 1. Edit not applied.`});else{let p=await S("fs.write",{path:be(t),content:d.replace(r,s)});if(p?.payload?.ok===!1)n.messages.push({role:"system",content:`Write failed: ${t} - ${p.payload.error||"unknown"}`});else{let g=i?.dataset.diffIdx;g!==void 0&&(n.messages[parseInt(g)]={role:"system",content:`Applied change to ${t}`})}}}catch(l){n.messages.push({role:"system",content:`Failed: ${t} - ${l.message}`})}k(),P()}function De(e){let t=e.dataset.idx;if(t!==void 0){let o=parseInt(t),r=n.messages[o]?.content.split("__")?.[3]||"file";n.messages[o]={role:"system",content:`Rejected change to ${r}`}}k(),P()}function qe(e,t){switch(e){case"select":Ue();break;case"screenshot":je();break;case"chat":xe("chat");break;case"settings":xe("settings");break;case"close-panel":ke();break;case"prompt-send":Se();break;case"save-settings":ze();break;case"get-key":{let o=t.dataset.url;o&&window.open(o,"_blank","noopener");break}case"apply-diff":Ae(t);break;case"reject-diff":De(t);break;case"clear-element":n.selectedElement=null,B();break;case"clear-screenshot":n.screenshot=null,B();break}}function W(){let e=w.querySelector(".om-status-dot");e&&(e.className=`om-status-dot ${n.connected?"connected":"disconnected"}`)}function N(){w.querySelectorAll(".om-pill-btn").forEach(e=>{let t=e.dataset.action;e.classList.toggle("active",t===n.activePanel||t==="select"&&n.selecting)})}function B(){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">${u.x}</button></span>`),n.screenshot&&e.push(`<span class="om-prompt-chip">Screenshot <button class="om-prompt-chip-x" data-action="clear-screenshot">${u.x}</button></span>`),we.innerHTML=e.join("")}function T(e){n.panelOpen=!0,n.activePanel=e,Y.classList.remove("om-hidden");let t=w.querySelector(".om-panel-title");t&&(t.textContent=e==="settings"?"Settings":"Chat"),k(),N()}function ke(){n.panelOpen=!1,n.activePanel="",Y.classList.add("om-hidden"),N()}function xe(e){n.panelOpen&&n.activePanel===e?ke():T(e)}function k(){n.activePanel==="settings"?x.innerHTML=Be():n.activePanel==="chat"&&(x.innerHTML=Ie(),P())}function Be(){let e=Object.entries(_).map(([g,m])=>`<option value="${g}" ${n.provider===g?"selected":""}>${m.name}</option>`).join(""),t=_[n.provider],o=t?t.models.map(g=>`<option value="${g.id}" ${n.model===g.id?"selected":""}>${g.name}</option>`).join(""):'<option value="">Select provider first</option>',a=t?.local||!1,r=t?.keyUrl||"",s=t?.keyPlaceholder||"Enter API key...",i=n.updateAvailable?`<div class="om-update-banner">v${n.latestVersion} available <code class="om-update-cmd">npx openmagic@latest</code></div>`:"",l=n.hasApiKey?`<div class="om-status om-status-success">${u.check} Connected</div>`:"",d=n.saveStatus==="saving"?'<span class="om-spinner"></span> Saving...':n.saveStatus==="saved"?`${u.check} Saved`:"Save",c=n.saveStatus==="saving"?"om-btn om-btn-saving":n.saveStatus==="saved"?"om-btn om-btn-saved":"om-btn",p=n.saveStatus==="saving"?"disabled":"";return`
|
|
326
326
|
${i}
|
|
327
327
|
<div class="om-settings">
|
|
328
328
|
<div class="om-field">
|
|
@@ -337,13 +337,13 @@
|
|
|
337
337
|
<label class="om-label">API Key</label>
|
|
338
338
|
<div class="om-key-row">
|
|
339
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}">${
|
|
340
|
+
${r?`<button class="om-btn-get-key" data-action="get-key" data-url="${r}">${u.externalLink} Get key</button>`:""}
|
|
341
341
|
</div>
|
|
342
342
|
${r?`<div class="om-key-hint"><a data-action="get-key" data-url="${r}">Get your ${t?.name||""} API key here</a></div>`:""}
|
|
343
343
|
</div>
|
|
344
|
-
<button class="${
|
|
344
|
+
<button class="${c}" data-action="save-settings" ${p}>${d}</button>
|
|
345
345
|
${l}
|
|
346
|
-
</div>`}function
|
|
346
|
+
</div>`}function Ie(){if(!n.provider||!n.hasApiKey&&!_[n.provider]?.local)return'<div class="om-status om-status-error">Configure your provider in Settings first</div>';let e=n.messages.map((a,r)=>{if(a.content.startsWith("__DIFF__"))try{let s=JSON.parse(X(a.content.slice(8))),i=V(s.search),l=V(s.replace);return`<div class="om-diff-card" data-diff-idx="${r}">
|
|
347
347
|
<div class="om-diff-file">${E(s.file)}</div>
|
|
348
348
|
<div class="om-diff-removed">${E(s.search.slice(0,200))}</div>
|
|
349
349
|
<div class="om-diff-added">${E(s.replace.slice(0,200))}</div>
|
|
@@ -351,5 +351,5 @@
|
|
|
351
351
|
<button class="om-btn om-btn-sm" data-action="apply-diff" data-file="${E(s.file)}" data-search="${i}" data-replace="${l}">Apply</button>
|
|
352
352
|
<button class="om-btn-secondary om-btn-sm" data-action="reject-diff" data-idx="${r}">Reject</button>
|
|
353
353
|
</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}">${E(a.content)}</div>`}).join(""),t=n.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${E(n.streamContent)}</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 P(){requestAnimationFrame(()=>{let e=
|
|
354
|
+
</div>`}catch{return'<div class="om-msg om-msg-system">Malformed diff data</div>'}return`<div class="om-msg om-msg-${a.role}">${E(a.content)}</div>`}).join(""),t=n.streaming?`<div class="om-msg om-msg-assistant"><span class="om-spinner"></span>${E(n.streamContent)}</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 P(){requestAnimationFrame(()=>{let e=x.querySelector(".om-chat-messages");e&&(e.scrollTop=e.scrollHeight)})}async function ze(){let t=x.querySelector('[data-field="apiKey"]')?.value||"";if(!n.provider){n.saveStatus="error",q(),setTimeout(()=>{n.saveStatus="",k()},2e3);return}if(!ae()){n.saveStatus="error",q();let a=x.querySelector('[data-action="save-settings"]');a&&(a.innerHTML="Not connected - check terminal"),setTimeout(()=>{n.saveStatus="",k()},3e3);return}let o={provider:n.provider,model:n.model};t&&(o.apiKey=t),n.saveStatus="saving",q();try{let a=await Promise.race([S("config.set",o),new Promise((r,s)=>setTimeout(()=>s(new Error("Save timed out")),8e3))]);n.hasApiKey=!!(t||n.hasApiKey),n.saveStatus="saved",q(),setTimeout(()=>{n.saveStatus="",n.activePanel==="settings"&&T("chat")},1200)}catch(a){n.saveStatus="error";let r=x.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(()=>{n.saveStatus="",k()},4e3)}}function q(){let e=x.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=`${u.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 Se(){let e=L.value.trim();if(!e||n.streaming)return;if(!n.provider||!n.hasApiKey&&!_[n.provider]?.local){T("settings");return}n.messages.push({role:"user",content:e}),n.streaming=!0,n.streamContent="",L.value="",T("chat");let t=fe(n.selectedElement,n.screenshot);t.pageUrl=window.location.href,t.pageTitle=document.title;let o=4,a=24e3,r=/\.(?:[cm]?[jt]sx?|svelte|vue|astro|html?|css|scss|less|php|py)$/i;try{let s=await S("fs.list",{});s?.payload?.projectTree&&(t.projectTree=s.payload.projectTree);let l=(s?.payload?.files||[]).filter(m=>m.type==="file"&&r.test(m.path)),d=[e,n.selectedElement?.tagName,n.selectedElement?.id,n.selectedElement?.className,n.selectedElement?.textContent].filter(Boolean).join(" ").toLowerCase().split(/[^a-z0-9_-]+/).filter(m=>m.length>=2),c=l.map(m=>{let v=0,O=m.path.toLowerCase();for(let R of d)O.includes(R)&&(v+=5);return/(component|page|route|app|src|view|template)/.test(O)&&(v+=2),{...m,score:v}}).sort((m,v)=>v.score-m.score),p=[],g=0;for(let m of c.slice(0,o)){if(g>=a)break;try{let v=n.roots[0]||"",O=await S("fs.read",{path:v?`${v}/${m.path}`:m.path}),R=String(O?.payload?.content||"");if(!R)continue;let Q=R.slice(0,Math.min(8e3,a-g));p.push({path:m.path,content:Q}),g+=Q.length}catch{}}p.length&&(t.files=p)}catch{}try{let s=await oe("llm.chat",{provider:n.provider,model:n.model,messages:n.messages.map(i=>({role:i.role,content:i.content})),context:t},i=>{n.streamContent+=i;let l=x.querySelector(".om-msg-assistant:last-child");l&&(l.innerHTML=`<span class="om-spinner"></span>${E(n.streamContent)}`,P())});if(n.messages.push({role:"assistant",content:n.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});n.messages.push({role:"system",content:`__DIFF__${V(d)}`})}}}catch(s){n.messages.push({role:"system",content:`Error: ${s.message}`})}n.streaming=!1,n.streamContent="",k(),P()}var $=null,H=null;function Ue(){n.selecting?J():I()}function I(){n.selecting=!0,document.body.style.cursor="crosshair",N(),H=t=>{let o=t.target;if(o.closest("openmagic-toolbar")||o.dataset?.openmagic)return;let a=o.getBoundingClientRect();re({x:a.x,y:a.y,width:a.width,height:a.height})},$=t=>{t.preventDefault(),t.stopPropagation();let o=t.target;o.closest("openmagic-toolbar")||o.dataset?.openmagic||(n.selectedElement=se(o),J(),B(),L.focus())};let e=t=>{t.key==="Escape"&&J()};document.addEventListener("mousemove",H,!0),document.addEventListener("click",$,!0),document.addEventListener("keydown",e,!0),I._escHandler=e}function J(){n.selecting=!1,document.body.style.cursor="",ie(),H&&(document.removeEventListener("mousemove",H,!0),H=null),$&&(document.removeEventListener("click",$,!0),$=null);let e=I._escHandler;e&&(document.removeEventListener("keydown",e,!0),I._escHandler=null),N()}async function je(){let e;try{let o=n.selectedElement?.cssSelector?.trim();o&&(e=document.querySelector(o)||void 0)}catch{}let t=await le(e||void 0);t&&(n.screenshot=t,B(),L.focus())}function Ge(){let e=!1,t=0,o=0,a=0,r=0;h.addEventListener("mousedown",s=>{let i=s.target;if(i.closest("[data-action]")||!i.closest(".om-grab")&&!i.closest(".om-pill-brand"))return;e=!0,t=s.clientX,o=s.clientY;let l=h.getBoundingClientRect();a=l.left,r=l.top,s.preventDefault()}),document.addEventListener("mousemove",s=>{e&&(h.style.left=a+s.clientX-t+"px",h.style.top=r+s.clientY-o+"px",h.style.right="auto",h.style.bottom="auto")}),document.addEventListener("mouseup",()=>{if(e){e=!1;try{localStorage.setItem("__om_pos__",JSON.stringify({left:h.style.left,top:h.style.top}))}catch{}}})}function E(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}function Ke(){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=ve.split(".").map(Number);for(let a=0;a<3;a++){if((t[a]||0)>(o[a]||0)){n.updateAvailable=!0,n.latestVersion=e.version,Fe();return}if((t[a]||0)<(o[a]||0))return}}).catch(()=>{})}function Fe(){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",()=>T("settings"));let o=w.querySelector(".om-toolbar-header");o&&o.appendChild(t)}typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",ye):ye());})();
|
|
355
355
|
//# sourceMappingURL=index.global.js.map
|