mirror of
https://github.com/sune-org/store.git
synced 2026-04-07 11:02:14 +00:00
1 line
15 KiB
JSON
1 line
15 KiB
JSON
[{"id":"1qp2vkk","name":"Git Reset Hard","pinned":false,"avatar":"","url":"gh://sune-org/store/github-utilities/git-reset.sune","updatedAt":1774579731069,"settings":{"model":"anthropic/claude-opus-4.6","temperature":"","top_p":"","top_k":"","frequency_penalty":"","repetition_penalty":"","min_p":"","top_a":"","verbosity":"","reasoning_effort":"default","system_prompt":"","html":"<!-- Sune: GitHub Time Machine -->\n<div id=\"gitReverterSune\" class=\"w-full max-w-3xl mx-auto p-4 md:p-6 bg-slate-100 rounded-2xl font-sans text-gray-700\">\n\n<style>\n.neu-outset{box-shadow:5px 5px 10px #c5cdd8,-5px -5px 10px #fff}\n.neu-inset{box-shadow:inset 5px 5px 10px #c5cdd8,inset -5px -5px 10px #fff}\n.neu-outset-sm{box-shadow:2px 2px 5px #c5cdd8,-2px -2px 5px #fff}\n.neu-inset-sm{box-shadow:inset 2px 2px 5px #c5cdd8,inset -2px -2px 5px #fff}\n#gr_commitsList::-webkit-scrollbar{width:6px}\n#gr_commitsList::-webkit-scrollbar-track{background:transparent}\n#gr_commitsList::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:3px}\n@keyframes fadeIn{from{opacity:0}to{opacity:1}}\n@keyframes scaleIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n#gr_confirmModal .modal-bg{animation:fadeIn .2s ease-out forwards}\n#gr_confirmModal .modal-content{animation:scaleIn .2s ease-out forwards}\n.gr-row{display:grid;grid-template-columns:auto 1fr auto;gap:0.5rem;align-items:center;padding:0.4rem 0.5rem}\n.gr-row:hover{background:rgba(148,163,184,.12);border-radius:0.5rem}\n.gr-sha{font-size:10px;font-family:monospace;color:#64748b;background:#e2e8f0;padding:1px 5px;border-radius:4px;user-select:all}\n.gr-msg{font-size:13px;font-weight:600;color:#1e293b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.gr-meta{font-size:10px;color:#94a3b8}\n.gr-sentinel{height:1px}\n</style>\n\n<div class=\"flex items-center justify-between pb-4\">\n <h1 class=\"text-xl font-bold flex items-center gap-3 text-slate-600\">\n <i data-lucide=\"history\" class=\"w-6 h-6\"></i>\n GitHub Reset Hard Force Push\n </h1>\n <span class=\"text-xs font-mono bg-slate-200 text-slate-500 px-2 py-1 rounded-full\">v1.2</span>\n</div>\n\n<div class=\"mt-4\">\n <label for=\"gr_repoPathInput\" class=\"text-sm font-medium text-slate-600 mb-2 block\">Repository Path</label>\n <div class=\"flex flex-col sm:flex-row items-stretch gap-3\">\n <input type=\"text\" id=\"gr_repoPathInput\" placeholder=\"owner/repo@branch\"\n class=\"flex-grow w-full px-4 py-3 bg-slate-100 rounded-xl focus:outline-none transition-all duration-200 neu-outset focus:neu-inset\">\n <button id=\"gr_loadCommitsBtn\"\n class=\"w-full sm:w-auto px-6 py-3 bg-slate-100 text-slate-800 font-semibold rounded-xl hover:text-black active:neu-inset transition-all duration-200 flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed neu-outset\">\n <i data-lucide=\"arrow-down-circle\" class=\"w-4 h-4\"></i>\n <span>Load Commits</span>\n </button>\n </div>\n</div>\n\n<div id=\"gr_statusDisplay\" class=\"mt-4\"></div>\n\n<div id=\"gr_commitsContainer\" class=\"mt-4 hidden\">\n <div class=\"flex items-center justify-between mb-2\">\n <h2 class=\"text-md font-semibold text-slate-500\">Commit History</h2>\n <span id=\"gr_commitCount\" class=\"text-xs font-mono text-slate-400\"></span>\n </div>\n <div id=\"gr_commitsList\" class=\"max-h-[55vh] overflow-y-auto rounded-lg p-1 neu-inset\">\n </div>\n <div id=\"gr_loadMoreWrap\" class=\"hidden mt-2 text-center\">\n <button id=\"gr_loadMoreBtn\"\n class=\"px-5 py-2 text-xs font-semibold bg-slate-100 text-slate-700 rounded-lg neu-outset-sm hover:text-black active:neu-inset-sm transition-all disabled:opacity-50\">\n <span id=\"gr_loadMoreText\">Load more</span>\n </button>\n </div>\n</div>\n\n<div id=\"gr_confirmModal\" class=\"hidden fixed inset-0 z-[100] p-4 flex items-center justify-center\">\n <div class=\"modal-bg absolute inset-0 bg-black/40 backdrop-blur-sm\"></div>\n <div class=\"modal-content relative w-full max-w-md bg-slate-100 rounded-2xl p-6 neu-outset\">\n <div class=\"text-center\">\n <div class=\"mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 neu-outset-sm\">\n <i data-lucide=\"alert-triangle\" class=\"h-6 w-6 text-red-600\"></i>\n </div>\n <h3 class=\"mt-4 text-lg font-bold text-gray-900\">Confirm Branch Rewind</h3>\n <div class=\"mt-2 text-sm text-gray-600 space-y-2\">\n <p>You are about to <strong class=\"font-bold text-red-700\">force-repoint</strong> the branch:</p>\n <p id=\"gr_confirmBranchInfo\" class=\"font-mono bg-slate-200 p-2 rounded-md text-xs neu-inset-sm\"></p>\n <p>Type <strong id=\"gr_confirmRepoName\" class=\"font-bold\"></strong> to confirm.</p>\n </div>\n </div>\n <div class=\"mt-4\">\n <input type=\"text\" id=\"gr_confirmRepoInput\" autocomplete=\"off\"\n class=\"w-full text-center px-4 py-3 bg-slate-100 rounded-xl focus:outline-none transition-all duration-200 neu-outset focus:neu-inset focus:ring-2 focus:ring-red-400\">\n </div>\n <div class=\"mt-5 grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <button id=\"gr_cancelBtn\" type=\"button\"\n class=\"w-full rounded-xl px-4 py-2.5 bg-slate-100 font-medium text-gray-700 neu-outset hover:text-black active:neu-inset transition-all\">Cancel</button>\n <button id=\"gr_confirmBtn\" type=\"button\"\n class=\"w-full rounded-xl px-4 py-2.5 bg-red-500 font-medium text-white shadow-md hover:bg-red-600 disabled:bg-red-300 disabled:cursor-not-allowed transition-all\">Repoint & Force Push</button>\n </div>\n </div>\n</div>\n\n<script>\n(()=>{\nconst SID=window.SUNE?.id||'git_reverter_sune';\nconst $=(s,p=document)=>p.querySelector(s);\nconst root=$('#gitReverterSune');\nconst pathIn=$('#gr_repoPathInput',root);\nconst loadBtn=$('#gr_loadCommitsBtn',root);\nconst statusEl=$('#gr_statusDisplay',root);\nconst commitsCont=$('#gr_commitsContainer',root);\nconst commitsList=$('#gr_commitsList',root);\nconst countEl=$('#gr_commitCount',root);\nconst loadMoreWrap=$('#gr_loadMoreWrap',root);\nconst loadMoreBtn=$('#gr_loadMoreBtn',root);\nconst loadMoreText=$('#gr_loadMoreText',root);\nconst modal=$('#gr_confirmModal',root);\nconst confirmBranchInfo=$('#gr_confirmBranchInfo',root);\nconst confirmRepoNameEl=$('#gr_confirmRepoName',root);\nconst confirmRepoIn=$('#gr_confirmRepoInput',root);\nconst cancelBtn=$('#gr_cancelBtn',root);\nconst confirmBtn=$('#gr_confirmBtn',root);\n\nconst PER_PAGE=100;\nlet worker,isLoading=false,resetTarget=null;\nlet allCommits=[],currentPage=1,hasMore=false;\n\nconst workerCode=`\nself.onmessage=async e=>{\nconst{action,payload}=e.data;\nconst{path,token,sha,page,per_page}=payload;\nconst[owner,repoBranch]=(path||'').split('/');\nconst[repo,branch]=(repoBranch||'').split('@');\nif(!token)return self.postMessage({type:'error',message:'GitHub token not found. Set in Account Settings.'});\nif(!owner||!repo||!branch)return self.postMessage({type:'error',message:'Invalid format. Use: owner/repo@branch'});\nconst headers={'Authorization':'Bearer '+token,'Accept':'application/vnd.github.v3+json','X-GitHub-Api-Version':'2022-11-28'};\ntry{\nif(action==='getCommits'){\nconst pg=page||1,pp=per_page||100;\nconst res=await fetch('https://api.github.com/repos/'+owner+'/'+repo+'/commits?sha='+branch+'&per_page='+pp+'&page='+pg,{headers});\nconst data=await res.json();\nif(!res.ok)throw new Error(data.message||'HTTP '+res.status);\nconst link=res.headers.get('Link')||'';\nconst hasNext=link.includes('rel=\"next\"');\nself.postMessage({type:'commitsResult',data,page:pg,hasNext});\n}else if(action==='repointBranch'){\nif(!sha)throw new Error('Commit SHA missing.');\nconst res=await fetch('https://api.github.com/repos/'+owner+'/'+repo+'/git/refs/heads/'+branch,{\nmethod:'PATCH',headers:{...headers,'Content-Type':'application/json'},\nbody:JSON.stringify({sha,force:true})});\nconst data=await res.json();\nif(!res.ok)throw new Error(data.message||'Failed. Status: '+res.status);\nself.postMessage({type:'repointSuccess',message:'Branch repointed successfully.'});\n}\n}catch(error){self.postMessage({type:'error',message:error.message})}\n};`;\n\nconst renderStatus=(type,msg)=>{\nconst C={e:'red',s:'green',l:'blue'},\nI={e:'alert-circle',s:'check-circle-2',l:'loader-2'},\nt=type.charAt(0);\nstatusEl.innerHTML=`<div class=\"flex items-center gap-3 p-3 text-sm font-medium rounded-lg border bg-${C[t]}-100 border-${C[t]}-300 text-${C[t]}-800\"><i data-lucide=\"${I[t]}\" class=\"w-5 h-5 flex-shrink-0 ${t==='l'?'animate-spin':''}\"></i><span>${msg}</span></div>`;\nwindow.lucide?.createIcons();\n};\n\nconst relTime=d=>{\nconst s=Math.floor((Date.now()-new Date(d))/1e3);\nif(s<60)return s+'s ago';\nif(s<3600)return Math.floor(s/60)+'m ago';\nif(s<86400)return Math.floor(s/3600)+'h ago';\nif(s<2592000)return Math.floor(s/86400)+'d ago';\nreturn new Date(d).toLocaleDateString([],{month:'short',day:'numeric',year:'numeric'});\n};\n\nconst commitHTML=c=>{\nconst msg=c.commit.message.split('\\n')[0];\nconst author=c.commit.author;\nconst ava=c.author?`<img src=\"${c.author.avatar_url}&s=32\" class=\"w-5 h-5 rounded-full\" loading=\"lazy\">`\n:`<span class=\"w-5 h-5 rounded-full bg-slate-300 inline-block\"></span>`;\nreturn `<div class=\"gr-row\">\n${ava}\n<div class=\"min-w-0\">\n<div class=\"gr-msg\" title=\"${msg.replace(/\"/g,'"')}\">${msg.replace(/</g,'<')}</div>\n<div class=\"gr-meta\"><span class=\"gr-sha\">${c.sha.slice(0,7)}</span> · ${author.name} · ${relTime(author.date)}</div>\n</div>\n<button data-sha=\"${c.sha}\" title=\"Repoint here\"\nclass=\"repoint-btn flex-shrink-0 px-2 py-1 text-[11px] font-bold text-slate-600 bg-slate-100 rounded-md neu-outset-sm active:neu-inset-sm hover:text-black transition-all whitespace-nowrap\">\nReset here\n</button>\n</div>`;\n};\n\nconst appendCommits=(commits,clear)=>{\nif(clear)commitsList.innerHTML='';\ncommitsList.insertAdjacentHTML('beforeend',commits.map(commitHTML).join(''));\ncountEl.textContent=allCommits.length+(hasMore?'+':'')+' commits';\nloadMoreWrap.classList.toggle('hidden',!hasMore);\n};\n\nconst loadCommits=(page=1)=>{\nif(isLoading)return;\nconst path=pathIn.value.trim();\nif(!path)return renderStatus('error','Enter a repository path.');\nconst token=localStorage.getItem('gh_token')||'';\nif(!token)return renderStatus('error','GitHub token not found. Set in Account Settings.');\nisLoading=true;\nloadBtn.disabled=true;\nloadMoreBtn.disabled=true;\nloadMoreText.textContent='Loading...';\nif(page===1){\nallCommits=[];\ncommitsCont.classList.add('hidden');\nrenderStatus('loading',`Fetching commits for ${path}...`);\n}\nlocalStorage.setItem(`${SID}_last_path`,path);\nworker.postMessage({action:'getCommits',payload:{path,token,page,per_page:PER_PAGE}});\n};\n\nconst toggleModal=(show,sha)=>{\nif(show){\nconst[owner,repoBranch]=(pathIn.value.trim()||'').split('/');\nconst[repo,branch]=(repoBranch||'').split('@');\nif(!owner||!repo||!branch)return;\nresetTarget={sha,repo};\nconfirmBranchInfo.textContent=`${owner}/${repo}@${branch} → ${sha.slice(0,7)}`;\nconfirmRepoNameEl.textContent=repo;\nconfirmRepoIn.value='';\nconfirmBtn.disabled=true;\nmodal.classList.remove('hidden');\ndocument.body.style.overflow='hidden';\nconfirmRepoIn.focus();\n}else{\nmodal.classList.add('hidden');\ndocument.body.style.overflow='';\nresetTarget=null;\n}\n};\n\nconst handleRepoint=()=>{\nif(!resetTarget||isLoading)return;\nisLoading=true;\nconfirmBtn.disabled=true;\nconfirmBtn.innerHTML='<i data-lucide=\"loader-2\" class=\"w-5 h-5 animate-spin mx-auto\"></i>';\nwindow.lucide?.createIcons();\nconst token=localStorage.getItem('gh_token');\nworker.postMessage({action:'repointBranch',payload:{path:pathIn.value.trim(),token,sha:resetTarget.sha}});\n};\n\nworker=new Worker(URL.createObjectURL(new Blob([workerCode],{type:'application/javascript'})));\n\nworker.onmessage=e=>{\nconst{type,data,message,page,hasNext}=e.data;\nisLoading=false;\nloadBtn.disabled=false;\nloadMoreBtn.disabled=false;\nloadMoreText.textContent='Load more';\n\nif(type==='commitsResult'){\nstatusEl.innerHTML='';\ncurrentPage=page;\nhasMore=!!hasNext;\nallCommits.push(...data);\ncommitsCont.classList.remove('hidden');\nappendCommits(data,page===1);\n}else if(type==='repointSuccess'){\ntoggleModal(false);\nconfirmBtn.textContent='Repoint & Force Push';\nrenderStatus('success',message);\nsetTimeout(()=>loadCommits(1),1000);\n}else if(type==='error'){\nrenderStatus('error',message);\nif(allCommits.length===0)commitsCont.classList.add('hidden');\nconfirmBtn.textContent='Repoint & Force Push';\n}\n};\n\n// Infinite scroll\nconst io=new IntersectionObserver(entries=>{\nif(entries[0].isIntersecting&&hasMore&&!isLoading)loadCommits(currentPage+1);\n},{root:commitsList,rootMargin:'200px'});\n\nconst observeSentinel=()=>{\nlet s=commitsList.querySelector('.gr-sentinel');\nif(s)io.unobserve(s);\ns=document.createElement('div');\ns.className='gr-sentinel';\ncommitsList.appendChild(s);\nio.observe(s);\n};\n\nconst origAppend=appendCommits;\nconst patchedAppend=(commits,clear)=>{\norigAppend(commits,clear);\nobserveSentinel();\n};\n// Override\nconst _appendCommits=patchedAppend;\n\n// Re-bind worker handler with patched append\nworker.onmessage=e=>{\nconst{type,data,message,page,hasNext}=e.data;\nisLoading=false;\nloadBtn.disabled=false;\nloadMoreBtn.disabled=false;\nloadMoreText.textContent='Load more';\nif(type==='commitsResult'){\nstatusEl.innerHTML='';\ncurrentPage=page;\nhasMore=!!hasNext;\nallCommits.push(...data);\ncommitsCont.classList.remove('hidden');\n_appendCommits(data,page===1);\n}else if(type==='repointSuccess'){\ntoggleModal(false);\nconfirmBtn.textContent='Repoint & Force Push';\nrenderStatus('success',message);\nsetTimeout(()=>loadCommits(1),1000);\n}else if(type==='error'){\nrenderStatus('error',message);\nif(allCommits.length===0)commitsCont.classList.add('hidden');\nconfirmBtn.textContent='Repoint & Force Push';\n}\n};\n\nloadBtn.addEventListener('click',()=>loadCommits(1));\nloadMoreBtn.addEventListener('click',()=>{if(hasMore)loadCommits(currentPage+1)});\npathIn.addEventListener('keydown',e=>{if(e.key==='Enter')loadCommits(1)});\ncommitsList.addEventListener('click',e=>{\nconst btn=e.target.closest('.repoint-btn');\nif(btn?.dataset.sha)toggleModal(true,btn.dataset.sha);\n});\ncancelBtn.addEventListener('click',()=>toggleModal(false));\nmodal.querySelector('.modal-bg').addEventListener('click',()=>toggleModal(false));\nconfirmBtn.addEventListener('click',handleRepoint);\nconfirmRepoIn.addEventListener('input',()=>{\nconfirmBtn.disabled=confirmRepoIn.value!==resetTarget?.repo;\n});\n\npathIn.value=localStorage.getItem(`${SID}_last_path`)||'';\nwindow.lucide?.createIcons();\n})();\n</script>\n</div>\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,"img_output":false,"aspect_ratio":"1:1","image_size":"1K","ignore_master_prompt":false,"json_schema":""},"storage":{}}] |