Files
.sune/inline-commit.sune

1 line
12 KiB
Plaintext

[{"id":"jbcwown","name":"1 Click GitHub Commit","pinned":false,"avatar":"data:image/webp;base64,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","url":"gh://multipleof4/.sune/inline-commit.sune","updatedAt":1769549049573,"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":"You include this sune in the extension.html of any sune you use to code with.\nThen use this system prompt and you will get 1 click button to commit your code inside code blocks:\nIn the preceding line to code blocks, apply this format: \n<newline>\n<newline>\n[org/repo@branch/file](https://github.com/org/repo/blob/branch/file \"Fix/Feat/Refactor/etc: Summarize in less than 50chars your following edit\")\nYou can delete files like so:\n<newline>\n<newline>\n[org/repo@branch/file](https://github.com/org/repo/blob/branch/file \"Delete: Summarize in less than 50chars\")\n<newline>\n<newline>","html":"<!--\nSune: GitHub Commit & Delete Helper\nVersion: 3.1\n-->\n<div id=\"sune_github_helper\" x-data=\"{v:'3.1'}\" class=\"hidden\"></div>\n<script>\n(()=>{\nconst suneEl=document.getElementById('sune_github_helper');\nif(!suneEl)return;\nconst SUNE_NAME='[Sune: GitHub Helper]';\nconsole.log(`${SUNE_NAME} v3.1`);\n\nconst defC=['bg-slate-100','text-slate-700','hover:bg-slate-200'],\nokC=['bg-green-100','text-green-800'],errC=['bg-red-100','text-red-800'];\n\nconst safeJson=async r=>{const t=await r.text();try{return JSON.parse(t)}catch{return{message:t.slice(0,200)}}};\n\nconst deleteFile=async(btn,owner,repo,branch,path,commitMsg)=>{\nconst token=window.USER?.githubToken;\nif(!token){alert('GitHub token not set.');return}\nbtn.disabled=true;\nbtn.innerHTML='<span class=\"animate-pulse\">Checking...</span>';\nconst H={'Authorization':`Bearer ${token}`,'Accept':'application/vnd.github.v3+json'};\ntry{\nconst U=`https://api.github.com/repos/${owner}/${repo}/contents/${path}`;\nconst r1=await fetch(`${U}?ref=${branch}`,{headers:H});\nif(r1.status===404)throw new Error('File not found.');\nif(!r1.ok)throw new Error(`Get failed: ${(await safeJson(r1)).message}`);\nconst{sha}=await r1.json();\nif(!sha)throw new Error('No SHA.');\nbtn.innerHTML='<span class=\"animate-pulse\">Deleting...</span>';\nconst r2=await fetch(U,{method:'DELETE',headers:H,body:JSON.stringify({message:commitMsg?.trim()||`Delete ${path.split('/').pop()}`,sha,branch})});\nif(!r2.ok)throw new Error(`Delete failed: ${(await safeJson(r2)).message}`);\nbtn.classList.remove(...defC);btn.classList.add(...okC);\nbtn.innerHTML='<i data-lucide=\"check\" class=\"h-3.5 w-3.5\"></i> Deleted';\n}catch(e){\nalert(`${SUNE_NAME} Delete Failed:\\n\\n${e.message}`);\nbtn.classList.remove(...defC);btn.classList.add(...errC);\nbtn.innerHTML='<i data-lucide=\"x\" class=\"h-3.5 w-3.5\"></i> Failed';\nsetTimeout(()=>{btn.disabled=false;btn.classList.remove(...errC);btn.classList.add(...defC);btn.innerHTML='<i data-lucide=\"trash-2\" class=\"h-3.5 w-3.5\"></i> Delete';window.lucide?.createIcons()},4e3);\n}finally{window.lucide?.createIcons()}\n};\n\nconst commitFile=async(btn,owner,repo,branch,path,content,commitMsg)=>{\nconst token=window.USER?.githubToken;\nif(!token){alert('GitHub token not set.');return}\nbtn.disabled=true;\nbtn.innerHTML='<span class=\"animate-pulse\">Checking...</span>';\nconst H={'Authorization':`Bearer ${token}`,'Accept':'application/vnd.github.v3+json'};\ntry{\nconst r0=await fetch('https://api.github.com/user',{headers:H});\nif(!r0.ok)throw new Error('Token invalid.');\nconst uname=(await r0.json()).login;\nbtn.innerHTML='<span class=\"animate-pulse\">Committing...</span>';\nconst rRepo=await fetch(`https://api.github.com/repos/${owner}/${repo}`,{headers:H});\nif(rRepo.status===404){\nconst isOrg=owner.toLowerCase()!==uname.toLowerCase(),\nurl=isOrg?`https://api.github.com/orgs/${owner}/repos`:'https://api.github.com/user/repos',\nrc=await fetch(url,{method:'POST',headers:H,body:JSON.stringify({name:repo,private:false})});\nif(!rc.ok)throw new Error(`Create repo failed: ${(await safeJson(rc)).message}`);\n}else if(!rRepo.ok)throw new Error(`Repo check failed: ${(await safeJson(rRepo)).message}`);\nconst U=`https://api.github.com/repos/${owner}/${repo}/contents/${path}`;\nlet sha;\nconst rf=await fetch(`${U}?ref=${branch}`,{headers:H});\nif(rf.ok)sha=(await rf.json()).sha;\nelse if(rf.status!==404)throw new Error(`Get file failed: ${(await safeJson(rf)).message}`);\nconst msg=commitMsg?.trim()||(sha?`Update ${path.split('/').pop()}`:`Add ${path.split('/').pop()}`),\nb64=btoa(unescape(encodeURIComponent(content)));\nconst rp=await fetch(U,{method:'PUT',headers:H,body:JSON.stringify({message:msg,content:b64,sha,branch})});\nif(!rp.ok)throw new Error(`Commit failed: ${(await safeJson(rp)).message}`);\nbtn.classList.remove(...defC);btn.classList.add(...okC);\nbtn.innerHTML='<i data-lucide=\"check\" class=\"h-3.5 w-3.5\"></i> Success';\n}catch(e){\nalert(`${SUNE_NAME} Commit Failed:\\n\\n${e.message}`);\nbtn.classList.remove(...defC);btn.classList.add(...errC);\nbtn.innerHTML='<i data-lucide=\"x\" class=\"h-3.5 w-3.5\"></i> Failed';\nsetTimeout(()=>{btn.disabled=false;btn.classList.remove(...errC);btn.classList.add(...defC);btn.innerHTML='<i data-lucide=\"github\" class=\"h-3.5 w-3.5\"></i> Commit';window.lucide?.createIcons()},4e3);\n}finally{window.lucide?.createIcons()}\n};\n\nconst processBubble=b=>{\nif(!b||b.dataset.suneGchProcessed)return;\nlet added=false;\nb.querySelectorAll('p:not(:has(button.commit-btn))').forEach(p=>{\nconst a=p.querySelector('a');if(!a)return;\nconst m=a.textContent.trim().match(/^([^\\/]+)\\/([^\\/]+)@([^\\/]+)\\/(.+)$/);if(!m)return;\nconst[_,owner,repo,branch,path]=m,msg=a.title,isDel=(msg||'').toLowerCase().startsWith('delete:');\nconst btn=document.createElement('button');\nbtn.className='commit-btn ml-2 inline-flex items-center gap-1.5 rounded-md bg-slate-100 px-2 py-1 text-xs font-medium text-slate-700 hover:bg-slate-200 transition-colors';\nif(isDel){\nbtn.innerHTML='<i data-lucide=\"trash-2\" class=\"h-3.5 w-3.5\"></i> Delete';\nbtn.onclick=()=>deleteFile(btn,owner,repo,branch,path.trim(),msg);\np.append(btn);added=true;\n}else{\nconst pre=p.nextElementSibling;if(pre?.tagName!=='PRE')return;\nconst code=pre.querySelector('code')?.innerText;if(code==null)return;\nbtn.innerHTML='<i data-lucide=\"github\" class=\"h-3.5 w-3.5\"></i> Commit';\nbtn.onclick=()=>commitFile(btn,owner,repo,branch,path.trim(),code,msg);\np.append(btn);added=true;\n}\n});\nif(added){b.dataset.suneGchProcessed='true';window.lucide?.createIcons()}\nreturn added;\n};\n\nconst scan=()=>document.querySelectorAll('#messages .msg-bubble').forEach(processBubble);\nconst obs=new MutationObserver(ms=>{for(const m of ms)for(const n of m.addedNodes)if(n.nodeType===1){(n.matches?.('.msg-bubble')?[n]:n.querySelectorAll?.('.msg-bubble'))?.forEach(processBubble)}});\nconst onResp=e=>{const id=e?.detail?.message?.id;if(!id)return;let a=0;const t=()=>{a++;const b=window.getBubbleById(id);if(b&&processBubble(b))return;if(a<8)setTimeout(t,300)};setTimeout(t,150)};\nconst c=window.el?.composer,m=window.el?.messages;\nif(c&&m){obs.observe(m,{childList:true,subtree:true});c.addEventListener('sune:newSuneResponse',onResp);scan()}\nsuneEl.addEventListener('sune:unmount',()=>{obs.disconnect();c?.removeEventListener('sune:newSuneResponse',onResp)});\n})();\n</script>\n","extension_html":"<sune src='https://raw.githubusercontent.com/sune-org/store/refs/heads/main/sync.sune' private></sune>","hide_composer":true,"include_thoughts":false,"json_output":false,"img_output":false,"aspect_ratio":"1:1","image_size":"1K","ignore_master_prompt":false,"json_schema":""},"storage":{}}]