draply-dev 1.5.4 → 1.5.5

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/bin/cli.js CHANGED
@@ -112,10 +112,11 @@ async function callAI(cfg, prompt) {
112
112
  });
113
113
  }
114
114
 
115
- // OpenAI / Groq — compatible API
115
+ // OpenAI / Groq / Gemini — compatible API
116
116
  const hosts = {
117
117
  openai: ['api.openai.com', '/v1/chat/completions', 'gpt-4o-mini'],
118
- groq: ['api.groq.com', '/openai/v1/chat/completions', 'llama-3.3-70b-versatile']
118
+ groq: ['api.groq.com', '/openai/v1/chat/completions', 'llama-3.3-70b-versatile'],
119
+ gemini: ['generativelanguage.googleapis.com', '/v1beta/openai/chat/completions', 'gemini-2.5-flash']
119
120
  };
120
121
  const [hostname, apiPath, defaultModel] = hosts[provider] || hosts.groq;
121
122
  const body = JSON.stringify({ model: cfg.model || defaultModel, messages: [{ role: 'user', content: prompt }], temperature: 0.1, max_tokens: 8192 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "draply-dev",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "Visual overlay for any frontend project — move, resize, restyle live in the browser, save to CSS",
5
5
  "author": "Arman",
6
6
  "type": "commonjs",
package/src/overlay.js CHANGED
@@ -678,6 +678,7 @@
678
678
 
679
679
  <div class="ps-foot">
680
680
  <button id="__ps_sv__" disabled>SAVE CHANGES</button>
681
+ <button id="__ps_ai_cfg__" style="width:100%;margin-top:8px;background:none;border:1px solid #2a2a3a;border-radius:6px;padding:6px;color:#5a5a7a;font-size:9px;cursor:pointer;letter-spacing:1px;text-transform:uppercase;transition:color .15s, border-color .15s" onmouseover="this.style.color='#7fff6e'; this.style.borderColor='#7fff6e'" onmouseout="this.style.color='#5a5a7a'; this.style.borderColor='#2a2a3a'">⚙️ AI Provider</button>
681
682
  </div>
682
683
  </div>
683
684
 
@@ -1769,6 +1770,21 @@ function revertChange(h) {
1769
1770
  }
1770
1771
  });
1771
1772
  updateUnsUI();
1773
+
1774
+ if (state.selectedEl) {
1775
+ const isVisible = document.body.contains(state.selectedEl) && getComputedStyle(state.selectedEl).display !== 'none';
1776
+ if (isVisible) {
1777
+ if (state.tool === 'mov') placeHdl(state.selectedEl);
1778
+ if (state.tool === 'rsz') placeRH(state.selectedEl);
1779
+ } else if (state.selectedEl === h.el) {
1780
+ state.selectedEl.classList.remove('__ps__', '__ps_multi__');
1781
+ state.selectedEl = null;
1782
+ state.selectedEls = [];
1783
+ hdl.classList.remove('v');
1784
+ Object.values(rhs).forEach(rh => rh.classList.remove('v'));
1785
+ }
1786
+ }
1787
+
1772
1788
  toast('↩ Reverted');
1773
1789
  }
1774
1790
 
@@ -1821,6 +1837,21 @@ function redoChange() {
1821
1837
  });
1822
1838
 
1823
1839
  updateUnsUI();
1840
+
1841
+ if (state.selectedEl) {
1842
+ const isVisible = document.body.contains(state.selectedEl) && getComputedStyle(state.selectedEl).display !== 'none';
1843
+ if (isVisible) {
1844
+ if (state.tool === 'mov') placeHdl(state.selectedEl);
1845
+ if (state.tool === 'rsz') placeRH(state.selectedEl);
1846
+ } else if (state.selectedEl === h.el) {
1847
+ state.selectedEl.classList.remove('__ps__', '__ps_multi__');
1848
+ state.selectedEl = null;
1849
+ state.selectedEls = [];
1850
+ hdl.classList.remove('v');
1851
+ Object.values(rhs).forEach(rh => rh.classList.remove('v'));
1852
+ }
1853
+ }
1854
+
1824
1855
  toast('↷ Redone');
1825
1856
  }
1826
1857
 
@@ -1837,7 +1868,7 @@ sv.addEventListener('click', async () => {
1837
1868
 
1838
1869
  if (!hasKey) {
1839
1870
  // Ask for provider first (#8)
1840
- const provider = prompt('Draply AI Save: Choose provider (groq / openai / anthropic / ollama):', 'groq');
1871
+ const provider = prompt('Draply AI Save: Choose provider (groq / openai / anthropic / gemini / ollama):', 'groq');
1841
1872
  if (!provider) { toast('Save aborted'); return; }
1842
1873
  const key = provider === 'ollama' ? 'local' : prompt(`Enter your ${provider.toUpperCase()} API key:`);
1843
1874
  if (key) {
@@ -1894,6 +1925,29 @@ document.getElementById('__uns_clear__').onclick = () => {
1894
1925
 
1895
1926
  document.getElementById('__uns_save__').onclick = () => sv.click();
1896
1927
 
1928
+ document.getElementById('__ps_ai_cfg__').onclick = async () => {
1929
+ const provider = prompt('Change AI Provider (groq / openai / anthropic / gemini / ollama):', 'groq');
1930
+ if (!provider) return;
1931
+ const key = provider === 'ollama' ? 'local' : prompt(`Enter your ${provider.toUpperCase()} API key:`);
1932
+
1933
+ if (!key && provider !== 'ollama') {
1934
+ toast('⚠ API Key required');
1935
+ return;
1936
+ }
1937
+
1938
+ toast('Verifying...');
1939
+ try {
1940
+ const vRes = await fetch('/draply-validate-key', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: key.trim(), provider: provider.trim() }) });
1941
+ const vData = await vRes.json();
1942
+ if (!vData.valid && provider !== 'ollama') {
1943
+ toast('⚠ Invalid API key'); return;
1944
+ }
1945
+ } catch { /* ignore validation fail */ }
1946
+
1947
+ await fetch('/draply-config', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey: key.trim(), provider: provider.trim() }) });
1948
+ toast('✅ AI Provider saved!');
1949
+ };
1950
+
1897
1951
  // ══════════════════════════════════════════
1898
1952
  // KEYBOARD SHORTCUTS (#4, #5, #15)
1899
1953
  // ══════════════════════════════════════════