mirror of
https://github.com/sune-org/store.git
synced 2026-01-13 16:17:58 +00:00
1 line
5.0 KiB
JSON
1 line
5.0 KiB
JSON
[{"id":"bthcn7s","name":"Log","pinned":false,"avatar":"","url":"gh://sune-org/store/log.sune","updatedAt":1757461552584,"settings":{"model":"openai/gpt-5-chat","temperature":"","top_p":"","top_k":"","frequency_penalty":"","repetition_penalty":"","min_p":"","top_a":"","verbosity":"","reasoning_effort":"default","system_prompt":"","html":"<div \n x-data=\"{\n state: {\n open: JSON.parse(localStorage.getItem(window.SUNE.id + '_logbox_open') || 'false'),\n copied: false\n },\n toggle() {\n this.state.open = !this.state.open;\n localStorage.setItem(window.SUNE.id + '_logbox_open', this.state.open);\n },\n copyLogs() {\n if (!this.$refs.logbox.innerText.trim()) return;\n navigator.clipboard.writeText(this.$refs.logbox.innerText).then(() => {\n this.state.copied = true;\n setTimeout(() => { this.state.copied = false }, 2000);\n }).catch(err => console.error('Sune Logbox: Failed to copy', err));\n }\n }\"\n x-init=\"lucide.createIcons()\"\n class=\"m-2 text-sm border rounded-lg bg-white shadow-lg dark:bg-gray-800 dark:border-gray-700\"\n>\n <div @click=\"toggle()\" class=\"flex items-center justify-between p-2 cursor-pointer border-b select-none dark:border-gray-700\">\n <div class=\"flex items-center gap-2 font-medium dark:text-gray-200\">\n <i data-lucide=\"terminal\" class=\"h-4 w-4\"></i>\n <span>Sune Console</span>\n </div>\n <div class=\"flex items-center gap-2\">\n <span class=\"text-xs text-gray-400\">v1.3.0</span>\n <button @click.stop=\"copyLogs()\" class=\"p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700\" title=\"Copy logs\">\n <i x-show=\"!state.copied\" data-lucide=\"copy\" class=\"h-4 w-4 text-gray-600 dark:text-gray-400\"></i>\n <i x-show=\"state.copied\" data-lucide=\"check\" class=\"h-4 w-4 text-green-500\"></i>\n </button>\n <button @click.stop=\"$refs.logbox.innerHTML=''\" class=\"p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700\" title=\"Clear logs\">\n <i data-lucide=\"trash-2\" class=\"h-4 w-4 text-gray-600 dark:text-gray-400\"></i>\n </button>\n <button @click.stop=\"toggle()\" class=\"p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700\" :aria-expanded=\"state.open\">\n <i x-show=\"!state.open\" data-lucide=\"chevron-down\" class=\"h-4 w-4 text-gray-600 dark:text-gray-400\"></i>\n <i x-show=\"state.open\" data-lucide=\"chevron-up\" class=\"h-4 w-4 text-gray-600 dark:text-gray-400\"></i>\n </button>\n </div>\n </div>\n <div x-show=\"state.open\" x-ref=\"logboxWrapper\" x-transition class=\"bg-gray-900 text-white font-mono text-xs p-2 max-h-80 overflow-y-auto rounded-b-lg\">\n <div x-ref=\"logbox\" class=\"whitespace-pre-wrap break-words\"></div>\n </div>\n</div>\n<script>\n(() => {\n const suneEl = document.currentScript.parentElement;\n const logbox = suneEl.querySelector('[x-ref=\"logbox\"]');\n if (!logbox) { console.error('Sune Logbox: Target element not found.'); return; }\n\n const oldConsole = { ...console };\n const esc = s => s.replace(/[&<>'\"]/g, c => ({'&':'&','<':'<','>':'>','\\'':''','\\\"':'"'}[c]));\n const formatArg = a => {\n if (typeof a === 'string') return esc(a);\n if (a instanceof Error) return esc(a.stack || a.message);\n try { return esc(JSON.stringify(a, null, 2)); } catch { return '[Unserializable]'; }\n };\n\n const print = (level, ...args) => {\n const c = { log:'text-gray-300', info:'text-blue-400', warn:'text-yellow-400', error:'text-red-400', debug:'text-purple-400' };\n const i = { log:'»', info:'ℹ', warn:'⚠', error:'✖', debug:'⚬' };\n const time = new Date().toLocaleTimeString([], { hour12: false });\n const content = args.map(formatArg).join(' ');\n const logHTML = `<div class=\"flex gap-2 items-start ${c[level] || c.log}\"><span class=\"opacity-50\">${time}</span><span class=\"font-bold\">${i[level] || ''}</span><span class=\"flex-1\">${content}</span></div>`;\n \n logbox.insertAdjacentHTML('beforeend', logHTML);\n logbox.parentElement.scrollTop = logbox.parentElement.scrollHeight;\n };\n\n const hook = level => { console[level] = (...a) => { oldConsole[level](...a); print(level, ...a); }; };\n ['log', 'warn', 'error', 'info', 'debug'].forEach(hook);\n\n const errHandler = e => print('error', e.error || e.reason || e.message || 'Unknown error');\n const rejectHandler = e => print('error', 'Unhandled Promise Rejection:', e.reason);\n window.addEventListener('error', errHandler);\n window.addEventListener('unhandledrejection', rejectHandler);\n\n const cleanup = () => {\n Object.assign(console, oldConsole);\n window.removeEventListener('error', errHandler);\n window.removeEventListener('unhandledrejection', rejectHandler);\n };\n \n suneEl.closest('#suneHtml')?.addEventListener('sune:unmount', cleanup, { once: true });\n print('info', 'Log catcher initialized.');\n})();\n</script>\n","extension_html":"<sune src='https://raw.githubusercontent.com/sune-org/store/refs/heads/main/sync.sune' private></sune>","hide_composer":false},"storage":{}}] |