This build was committed by a bot.

This commit is contained in:
github-actions[bot]
2025-11-09 05:20:59 +00:00
parent 8a86f6f3a6
commit d99ec2bcef
3 changed files with 3 additions and 1627 deletions

File diff suppressed because it is too large Load Diff

170
dist/index.html vendored
View File

@@ -7,14 +7,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/tiny-ripple@0.2.0"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@5.8.1/github-markdown-light.min.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.11.1/build/styles/github.min.css"/>
<script defer src="https://cdn.jsdelivr.net/npm/cash-dom/dist/cash.min.js"></script>
<script defer src="//unpkg.com/alpinejs"></script>
<script type="module" crossorigin src="/assets/index-_QTPhrhq.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-aer9aH6o.css">
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
<body class="bg-white text-gray-900 selection:bg-black/10" x-data @click.window="if($event.target.closest('button')) haptic(); if(!document.getElementById('threadPopover').contains($event.target)&&!$event.target.closest('[data-thread-menu]')) hideThreadPopover(); if(!document.getElementById('sunePopover').contains($event.target)&&!$event.target.closest('[data-sune-menu]')) hideSunePopover(); if(!document.getElementById('userMenu').contains($event.target)&&!document.getElementById('userMenuBtn').contains($event.target)) document.getElementById('userMenu').classList.add('hidden')">
@@ -159,169 +158,4 @@
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">JSON Schema</label>
<pre id="jsonSchemaEditor" class="w-full h-48 p-3 rounded-xl border border-gray-300 bg-white overflow-auto font-mono" contenteditable="plaintext-only" spellcheck="false" autocorrect="off" autocapitalize="off" autocomplete="off"></pre>
<p class="mt-1 text-xs text-gray-500">Requires "JSON Output" to be enabled. Value for <code>json_schema</code>.</p>
</div>
</div>
<div id="panelScript" class="p-1 hidden">
<div class="border-b flex text-xs font-medium">
<button type="button" id="htmlTab_index" class="flex-1 py-2 px-3 text-center border-b-2"></button>
<button type="button" id="htmlTab_extension" class="flex-1 py-2 px-3 text-center border-b-2"></button>
</div>
<div class="pt-0">
<pre id="htmlEditor" class="w-full h-[50vh] p-3 rounded-xl border border-gray-300 bg-white overflow-auto font-mono text-[12px] leading-5" contenteditable="plaintext-only" spellcheck="false" autocorrect="off" autocapitalize="off" autocomplete="off"></pre>
<pre id="extensionHtmlEditor" class="w-full h-[50vh] p-3 rounded-xl border border-gray-300 bg-white overflow-auto font-mono text-[12px] leading-5 hidden" contenteditable="plaintext-only" spellcheck="false" autocorrect="off" autocapitalize="off" autocomplete="off"></pre>
</div>
<div class="mt-2 flex gap-2">
<button type="button" id="copyHTML" class="px-3 py-1.5 rounded-lg bg-gray-100 hover:bg-gray-200">Copy</button>
<button type="button" id="pasteHTML" class="px-3 py-1.5 rounded-lg bg-gray-100 hover:bg-gray-200">Paste</button>
</div>
<p class="mt-1 text-xs text-gray-500">Scripts also run. extension.html runs before index.html.</p>
</div>
<div class="flex items-center justify-between gap-2 px-4 py-3 border-t">
<button type="button" id="deleteSuneBtn" class="inline-flex items-center gap-2 px-3 py-2 rounded-xl border border-red-200 text-red-700 hover:bg-red-50">
<svg viewBox="0 0 24 24" class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 6h18M8 6v12a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V6m-9 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
<span>Delete sune</span>
</button>
<div class="flex items-center justify-end gap-2">
<button type="button" id="cancelSettings" class="px-3 py-2 rounded-xl border bg-white hover:bg-gray-50">Cancel</button>
<button type="submit" class="px-3 py-2 rounded-xl bg-black text-white hover:bg-black/90">Save</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div id="accountSettingsModal" class="hidden fixed inset-0 z-50">
<div class="absolute inset-0 bg-black/30"></div>
<div class="absolute inset-x-0 top-16 mx-auto w-full max-w-md px-4">
<div class="rounded-2xl bg-white shadow-xl border border-gray-200 overflow-hidden">
<div class="px-4 py-3 border-b text-sm font-semibold flex items-center justify-between">
<span>Account Settings</span>
<button id="closeAccountSettings" class="p-1 rounded hover:bg-gray-100" aria-label="Close">
<svg viewBox="0 0 24 24" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
</button>
</div>
<form id="accountSettingsForm" class="text-sm">
<div class="border-b flex text-xs font-medium">
<button type="button" id="accountTabGeneral" class="flex-1 py-2 px-3 text-center border-b-2 border-black">General</button>
<button type="button" id="accountTabAPI" class="flex-1 py-2 px-3 text-center border-b-2 border-transparent hover:border-gray-300">API</button>
<button type="button" id="accountTabUser" class="flex-1 py-2 px-3 text-center border-b-2 border-transparent hover:border-gray-300">User</button>
</div>
<div id="accountPanelGeneral" class="p-4 space-y-4">
<div>
<label class="block text-gray-700 font-medium mb-1">Provider</label>
<select id="set_provider" class="w-full rounded-xl border border-gray-300 px-3 py-2">
<option value="openrouter">OpenRouter</option>
<option value="openai">OpenAI</option>
<option value="google">Google</option>
<option value="claude">Claude</option>
<option value="cloudflare">Cloudflare</option>
</select>
<p class="mt-1 text-xs text-gray-500">Or you can prefix model names with or:, oai:, g:, cla:, or cf: to override.</p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">Master Prompt</label>
<textarea id="set_master_prompt" rows="6" class="w-full rounded-xl border border-gray-300 px-3 py-2" placeholder="Applies to all sunes on this device"></textarea>
<p class="mt-1 text-xs text-gray-500">Stored locally.</p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">Model preference for titles</label>
<input id="set_title_model" type="text" class="w-full rounded-xl border border-gray-300 px-3 py-2" placeholder="or:google/gemma-3-12b-it"/>
<p class="mt-1 text-xs text-gray-500">Used for auto-generating thread titles.</p>
</div>
</div>
<div id="accountPanelAPI" class="p-4 hidden">
<div class="grid grid-cols-2 gap-x-4 gap-y-4">
<div>
<label class="block text-gray-700 font-medium mb-1">OpenRouter Key</label>
<div class="relative">
<input id="set_api_key_or" type="password" class="w-full rounded-xl border border-gray-300 px-3 py-2 pr-10" placeholder="sk-or-...">
<button type="button" data-reveal-for="set_api_key_or" class="absolute inset-y-0 right-0 px-3 flex items-center text-gray-400 hover:text-gray-600"><i data-lucide="eye" class="h-4 w-4"></i></button>
</div>
<p class="mt-1 text-xs text-gray-500">Use: <code>USER.apiKeyOpenRouter</code></p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">OpenAI Key</label>
<div class="relative">
<input id="set_api_key_oai" type="password" class="w-full rounded-xl border border-gray-300 px-3 py-2 pr-10" placeholder="sk-...">
<button type="button" data-reveal-for="set_api_key_oai" class="absolute inset-y-0 right-0 px-3 flex items-center text-gray-400 hover:text-gray-600"><i data-lucide="eye" class="h-4 w-4"></i></button>
</div>
<p class="mt-1 text-xs text-gray-500">Use: <code>USER.apiKeyOpenAI</code></p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">Google Key</label>
<div class="relative">
<input id="set_api_key_g" type="password" class="w-full rounded-xl border border-gray-300 px-3 py-2 pr-10" placeholder="AIza...">
<button type="button" data-reveal-for="set_api_key_g" class="absolute inset-y-0 right-0 px-3 flex items-center text-gray-400 hover:text-gray-600"><i data-lucide="eye" class="h-4 w-4"></i></button>
</div>
<p class="mt-1 text-xs text-gray-500">Gemini/Studio. Use: <code>USER.apiKeyGoogle</code></p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">Claude Key</label>
<div class="relative">
<input id="set_api_key_claude" type="password" class="w-full rounded-xl border border-gray-300 px-3 py-2 pr-10" placeholder="sk-ant-...">
<button type="button" data-reveal-for="set_api_key_claude" class="absolute inset-y-0 right-0 px-3 flex items-center text-gray-400 hover:text-gray-600"><i data-lucide="eye" class="h-4 w-4"></i></button>
</div>
<p class="mt-1 text-xs text-gray-500">Use: <code>USER.apiKeyClaude</code></p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">Cloudflare Token</label>
<div class="relative">
<input id="set_api_key_cf" type="password" class="w-full rounded-xl border border-gray-300 px-3 py-2 pr-10" placeholder="...">
<button type="button" data-reveal-for="set_api_key_cf" class="absolute inset-y-0 right-0 px-3 flex items-center text-gray-400 hover:text-gray-600"><i data-lucide="eye" class="h-4 w-4"></i></button>
</div>
<p class="mt-1 text-xs text-gray-500">Not used. Use: <code>USER.apiKeyCloudflare</code></p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">Github Token</label>
<div class="relative">
<input id="set_gh_token" type="password" class="w-full rounded-xl border border-gray-300 px-3 py-2 pr-10" placeholder="ghp_...">
<button type="button" data-reveal-for="set_gh_token" class="absolute inset-y-0 right-0 px-3 flex items-center text-gray-400 hover:text-gray-600"><i data-lucide="eye" class="h-4 w-4"></i></button>
</div>
<p class="mt-1 text-xs text-gray-500">Use: <code>USER.githubToken</code></p>
</div>
<div>
<label class="block text-gray-700 font-medium mb-1">GCP Service Acct</label>
<input id="gcpSAInput" type="file" class="hidden" accept="application/json,.json">
<button type="button" id="gcpSAUploadBtn" class="w-full text-left rounded-xl border border-gray-300 bg-white px-3 py-2 text-sm hover:bg-gray-50 truncate">Upload .json</button>
<p class="mt-1 text-xs text-gray-500">Use: <code>USER.gcpSA</code></p>
</div>
</div>
</div>
<div id="accountPanelUser" class="p-4 space-y-4 hidden">
<div class="flex items-center gap-4">
<div class="relative">
<img id="userAvatarPreview" class="h-16 w-16 rounded-full object-cover bg-gray-200">
<button type="button" id="setUserAvatarBtn" class="absolute bottom-0 right-0 h-6 w-6 rounded-full bg-white border border-gray-300 flex items-center justify-center hover:bg-gray-100" aria-label="Edit photo">
<i data-lucide="edit-3" class="h-3 w-3"></i>
</button>
</div>
<input id="userAvatarInput" type="file" accept="image/*" class="hidden">
<div class="flex-1">
<label for="set_user_name" class="block text-gray-700 font-medium mb-1">Username</label>
<input id="set_user_name" type="text" class="w-full rounded-xl border border-gray-300 px-3 py-2" placeholder="Master"/>
</div>
</div>
</div>
<div class="flex items-center justify-between gap-2 px-4 py-3 border-t">
<div class="flex items-center gap-2">
<button type="button" id="importAccountSettings" class="text-xs px-2.5 py-1.5 rounded-lg border bg-white hover:bg-gray-50">Import</button>
<button type="button" id="exportAccountSettings" class="text-xs px-2.5 py-1.5 rounded-lg border bg-white hover:bg-gray-50">Export</button>
</div>
<div class="flex items-center justify-end gap-2">
<button type="button" id="cancelAccountSettings" class="px-3 py-2 rounded-xl border bg-white hover:bg-gray-50">Cancel</button>
<button type="submit" class="px-3 py-2 rounded-xl bg-black text-white hover:bg-black/90">Save</button>
</div>
</div>
</form>
</div>
</div>
</div>
<input id="importAccountSettingsInput" type="file" class="hidden" accept="application/json,.json">
<script src="https://unpkg.com/lucide@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/localforage@1.10.0/dist/localforage.min.js"></script>
</body>
</html>
<pre id="jsonSchemaEditor" class="w-full h-48 p-3 rounded-xl border border-gray-300 bg-white overflow-auto font-mono" contenteditable="plaintext-only" spellcheck="false" autocorrect="off" autocapitalize="

2
dist/sw.js vendored
View File

@@ -1 +1 @@
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didnt register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const d=e=>i(e,t),l={module:{uri:t},exports:o,require:d};s[t]=Promise.all(n.map(e=>l[e]||d(e))).then(e=>(r(...e),o))}}define(["./workbox-5ffe50d4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"assets/index-_QTPhrhq.js",revision:null},{url:"assets/index-aer9aH6o.css",revision:null},{url:"index.html",revision:"dd36148740f64850094b2c097bd38855"},{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"manifest.webmanifest",revision:"7a6c5c6ab9cb5d3605d21df44c6b17a2"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
if(!self.define){let e,i={};const s=(s,n)=>(s=new URL(s+".js",n).href,i[s]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()}).then(()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didnt register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(i[t])return;let o={};const c=e=>s(e,t),d={module:{uri:t},exports:o,require:c};i[t]=Promise.all(n.map(e=>d[e]||c(e))).then(e=>(r(...e),o))}}define(["./workbox-5ffe50d4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"assets/index-aer9aH6o.css",revision:null},{url:"index.html",revision:"77c31065ccdcb5ee396b60958a2d40d5"},{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"manifest.webmanifest",revision:"7a6c5c6ab9cb5d3605d21df44c6b17a2"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});