mirror of
https://github.com/sune-org/store.git
synced 2026-01-13 16:17:58 +00:00
1 line
9.9 KiB
JSON
1 line
9.9 KiB
JSON
[{"id":"7tcehix","name":"Github Rate Limit","pinned":false,"avatar":"","url":"gh://sune-org/store/github-utilities/github-ratelimit.sune","updatedAt":1762718343720,"settings":{"model":"google/gemini-2.5-pro","temperature":"","top_p":"","top_k":"","frequency_penalty":"","repetition_penalty":"","min_p":"","top_a":"","verbosity":"","reasoning_effort":"default","system_prompt":"","html":"<section id=\"rateLimitSune\" class=\"mx-3 my-3 max-w-xl rounded-2xl border border-gray-200 bg-white/95 shadow-sm px-3 py-2 space-y-2 text-xs text-gray-800\">\n <div class=\"flex items-center justify-between gap-2\">\n <div class=\"flex items-center gap-2\">\n <span class=\"inline-flex h-6 w-6 items-center justify-center rounded-full bg-gray-900 text-white text-xs\">✺</span>\n <div class=\"leading-tight\">\n <div class=\"font-semibold text-[11px] tracking-wide uppercase text-gray-600\">\n GitHub Rate Limits\n </div>\n <div class=\"text-[10px] text-gray-400\">\n v1.0.0 · Live from api.github.com/rate_limit\n </div>\n </div>\n </div>\n <button id=\"ghRateRefresh\" class=\"h-7 px-2 flex items-center gap-1 rounded-xl bg-gray-900 text-white text-[9px] hover:bg-gray-800 active:scale-[.97] transition\">\n <svg class=\"w-3 h-3\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 12a9 9 0 0 0-9-9 9.002 9.002 0 0 0-8.485 6M3 12a9 9 0 0 0 9 9 9.002 9.002 0 0 0 8.485-6M3 3v6h6M21 21v-6h-6\"/>\n </svg>\n <span>Refresh</span>\n </button>\n </div>\n\n <div class=\"grid grid-cols-2 gap-2\">\n <div class=\"border border-gray-100 rounded-xl px-2 py-1.5 bg-gray-50/80\">\n <div class=\"flex items-center justify-between gap-1 mb-0.5\">\n <span class=\"font-semibold text-[9px] text-gray-600 uppercase tracking-wide\">Unauthenticated</span>\n <span id=\"ghNoTokenStatus\" class=\"text-[8px] px-1.5 py-0.5 rounded-full bg-gray-200 text-gray-700\">…</span>\n </div>\n <div class=\"flex items-baseline gap-1\">\n <span id=\"ghNoTokenRemaining\" class=\"font-semibold text-[15px] text-gray-900\">-</span>\n <span class=\"text-[8px] text-gray-500\">remaining</span>\n </div>\n <div class=\"flex items-center justify-between gap-1\">\n <div class=\"flex flex-col\">\n <span class=\"text-[8px] text-gray-500\">Limit</span>\n <span id=\"ghNoTokenLimit\" class=\"text-[9px] text-gray-700\">-</span>\n </div>\n <div class=\"flex flex-col text-right\">\n <span class=\"text-[8px] text-gray-500\">Resets</span>\n <span id=\"ghNoTokenReset\" class=\"text-[8px] text-gray-700\">-</span>\n </div>\n </div>\n <div class=\"mt-1 h-1.5 w-full bg-gray-200 rounded-full overflow-hidden\">\n <div id=\"ghNoTokenBar\" class=\"h-full bg-gray-900 rounded-full transition-all duration-300\" style=\"width:0%\"></div>\n </div>\n </div>\n\n <div class=\"border border-gray-100 rounded-xl px-2 py-1.5 bg-gray-50/80\">\n <div class=\"flex items-center justify-between gap-1 mb-0.5\">\n <span class=\"font-semibold text-[9px] text-gray-600 uppercase tracking-wide flex items-center gap-1\">\n With Token\n <span id=\"ghTokenDot\" class=\"inline-block w-1.5 h-1.5 rounded-full bg-gray-300\"></span>\n </span>\n <span id=\"ghTokenStatus\" class=\"text-[8px] px-1.5 py-0.5 rounded-full bg-gray-200 text-gray-700\">No token</span>\n </div>\n <div class=\"flex items-baseline gap-1\">\n <span id=\"ghTokenRemaining\" class=\"font-semibold text-[15px] text-gray-900\">-</span>\n <span class=\"text-[8px] text-gray-500\">remaining</span>\n </div>\n <div class=\"flex items-center justify-between gap-1\">\n <div class=\"flex flex-col\">\n <span class=\"text-[8px] text-gray-500\">Limit</span>\n <span id=\"ghTokenLimit\" class=\"text-[9px] text-gray-700\">-</span>\n </div>\n <div class=\"flex flex-col text-right\">\n <span class=\"text-[8px] text-gray-500\">Resets</span>\n <span id=\"ghTokenReset\" class=\"text-[8px] text-gray-700\">-</span>\n </div>\n </div>\n <div class=\"mt-1 h-1.5 w-full bg-gray-200 rounded-full overflow-hidden\">\n <div id=\"ghTokenBar\" class=\"h-full bg-gray-900 rounded-full transition-all duration-300\" style=\"width:0%\"></div>\n </div>\n </div>\n </div>\n\n <div class=\"flex items-center gap-1 justify-between\">\n <div class=\"flex items-center gap-1\">\n <span class=\"inline-flex items-center rounded-full bg-gray-50 text-[7px] px-1.5 py-0.5 text-gray-500\">\n Uses USER.githubToken if set. No token is stored on our servers.\n </span>\n </div>\n <div class=\"flex items-center gap-1 text-[7px] text-gray-400\">\n <span id=\"ghRateUpdatedAt\">Last: —</span>\n </div>\n </div>\n\n <script>\n ;(()=>{const S=window.SUNE?.id||\"gh-rate-limit\"\n const Q=e=>document.getElementById(e)\n const T=(u=0)=>{if(!u)return\"–\";const d=new Date(u*1e3),n=new Date(Date.now())\n const m=Math.max(0,Math.round((d-n)/6e4))\n return m?m+\"m (\"+d.toLocaleTimeString()+\")\":\"now\"}\n const B=(r,l)=>{if(!l||!r)return\"0%\";const p=Math.max(0,Math.min(1,r/l));return(100*p).toFixed(0)+\"%\"}\n const U=ts=>{Q(\"ghRateUpdatedAt\").textContent=\"Last: \"+(ts?new Date(ts).toLocaleTimeString():\"—\")}\n const L=(p,b)=>{if(!p||!p.remaining&&p.remaining!==0)return{remaining:\"-\",limit:\"-\",reset:\"–\",bar:\"0%\"}\n return{\n remaining:p.remaining,\n limit:p.limit,\n reset:T(p.reset),\n bar:B(p.remaining,p.limit)\n }}\n const F=async(h,token)=>{try{\n const r=await fetch(\"https://api.github.com/rate_limit\",{headers:h})\n const j=await r.json()\n return{ok:r.ok,data:j,error:!r.ok?j?.message||r.statusText:\"\",ts:r.headers.get(\"date\")?Date.parse(r.headers.get(\"date\")):Date.now()}\n }catch(e){return{ok:!1,data:null,error:e.message,ts:Date.now()}}}\n const P=async()=>{const token=window.USER?.githubToken||window.USER?.ghToken\n const has=!!token\n const headersBase={'Accept':'application/vnd.github+json'}\n const [noTok, tok]=await Promise.all([\n F(headersBase),\n has?F({...headersBase,'Authorization':\"Bearer \"+token,'X-GitHub-Api-Version':'2022-11-28'}):Promise.resolve({ok:!1,data:null,error:\"No token\",ts:Date.now()})\n ])\n // unauth\n if(noTok.data?.resources?.core){\n const s=L(noTok.data.resources.core,\"ghNoTokenBar\")\n Q(\"ghNoTokenRemaining\").textContent=s.remaining\n Q(\"ghNoTokenLimit\").textContent=s.limit\n Q(\"ghNoTokenReset\").textContent=s.reset\n Q(\"ghNoTokenBar\").style.width=s.bar\n Q(\"ghNoTokenStatus\").textContent=noTok.ok?\"OK\":\"Err\"\n }else{\n Q(\"ghNoTokenRemaining\").textContent=\"-\"\n Q(\"ghNoTokenLimit\").textContent=\"-\"\n Q(\"ghNoTokenReset\").textContent=\"–\"\n Q(\"ghNoTokenBar\").style.width=\"0%\"\n Q(\"ghNoTokenStatus\").textContent=\"Err\"\n }\n // token\n const dot=Q(\"ghTokenDot\"),st=Q(\"ghTokenStatus\")\n if(!has){\n st.textContent=\"No token\"\n dot.className=\"inline-block w-1.5 h-1.5 rounded-full bg-gray-300\"\n Q(\"ghTokenRemaining\").textContent=\"-\"\n Q(\"ghTokenLimit\").textContent=\"-\"\n Q(\"ghTokenReset\").textContent=\"–\"\n Q(\"ghTokenBar\").style.width=\"0%\"\n }else if(tok.data?.resources?.core){\n const s=L(tok.data.resources.core,\"ghTokenBar\")\n Q(\"ghTokenRemaining\").textContent=s.remaining\n Q(\"ghTokenLimit\").textContent=s.limit\n Q(\"ghTokenReset\").textContent=s.reset\n Q(\"ghTokenBar\").style.width=s.bar\n st.textContent=tok.ok?\"Token OK\":\"Token Err\"\n dot.className=\"inline-block w-1.5 h-1.5 rounded-full \"+(tok.ok?\"bg-emerald-500\":\"bg-amber-400\")\n }else{\n st.textContent=tok.error||\"Token Err\"\n dot.className=\"inline-block w-1.5 h-1.5 rounded-full bg-amber-400\"\n Q(\"ghTokenRemaining\").textContent=\"-\"\n Q(\"ghTokenLimit\").textContent=\"-\"\n Q(\"ghTokenReset\").textContent=\"–\"\n Q(\"ghTokenBar\").style.width=\"0%\"\n }\n U(tok.ts||noTok.ts)\n try{localStorage.setItem(S,JSON.stringify({noTok,tok,at:Date.now()}))}catch{}\n }\n // hydrate from cache (fast)\n ;(()=>{try{\n const c=localStorage.getItem(S);if(!c)return\n const{noTok,tok,at}=JSON.parse(c)||{}\n if(noTok?.data?.resources?.core){\n const s=L(noTok.data.resources.core)\n Q(\"ghNoTokenRemaining\").textContent=s.remaining\n Q(\"ghNoTokenLimit\").textContent=s.limit\n Q(\"ghNoTokenReset\").textContent=s.reset\n Q(\"ghNoTokenBar\").style.width=s.bar\n Q(\"ghNoTokenStatus\").textContent=noTok.ok?\"OK\":\"Err\"\n }\n if(tok){\n const has=!!(window.USER?.githubToken||window.USER?.ghToken)\n const dot=Q(\"ghTokenDot\"),st=Q(\"ghTokenStatus\")\n if(has&&tok.data?.resources?.core){\n const s=L(tok.data.resources.core)\n Q(\"ghTokenRemaining\").textContent=s.remaining\n Q(\"ghTokenLimit\").textContent=s.limit\n Q(\"ghTokenReset\").textContent=s.reset\n Q(\"ghTokenBar\").style.width=s.bar\n st.textContent=tok.ok?\"Token OK\":\"Token Err\"\n dot.className=\"inline-block w-1.5 h-1.5 rounded-full \"+(tok.ok?\"bg-emerald-500\":\"bg-amber-400\")\n }else if(!has){\n st.textContent=\"No token\"\n dot.className=\"inline-block w-1.5 h-1.5 rounded-full bg-gray-300\"\n }\n }\n U(at)\n }catch(e){}\n })()\n Q(\"ghRateRefresh\").onclick=e=>{e.preventDefault();P()}\n P()\n })()\n </script>\n</section>\n","extension_html":"<sune src='https://raw.githubusercontent.com/sune-org/store/refs/heads/main/sync.sune' private></sune>","hide_composer":false,"include_thoughts":false,"json_output":false,"ignore_master_prompt":false,"json_schema":""},"storage":{}}] |