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