KS
Pilih percakapanCari pengguna untuk mulai chat
PRIBADI
Logo King Santosa
'},active:'index.html'},handle=null;try{data=JSON.parse(localStorage.getItem(key))||data}catch{};const save=()=>localStorage.setItem(key,JSON.stringify(data));const esc=s=>String(s).replace(/[&<>]/g,c=>({'&':'&','<':'<','>':'>'}[c]));const render=()=>{filesBox.innerHTML=Object.keys(data.files).sort().map(p=>'').join('');filesBox.querySelectorAll('[data-file]').forEach(b=>b.onclick=()=>{data.files[data.active]=editor.value;data.active=b.dataset.file;editor.value=data.files[data.active]||'';save();render()});editor.value=data.files[data.active]||''};const write=async(path,content)=>{data.files[path]=content;if(handle){let parts=path.split('/'),file=parts.pop(),dir=handle;for(const part of parts)dir=await dir.getDirectoryHandle(part,{create:true});const target=await dir.getFileHandle(file,{create:true}),stream=await target.createWritable();await stream.write(content);await stream.close()}};const launch=()=>{modal.hidden=false;render();setTimeout(()=>editor.focus(),0)};const addButton=()=>{if(!window.ksUserChatAssistantOpen||document.getElementById('ks-code-launch'))return;const target=document.getElementById('uc-peer-sub');if(!target)return;const b=document.createElement('button');b.id='ks-code-launch';b.className='ks-code-launch';b.type='button';b.textContent=' Code';b.onclick=launch;target.after(b)};new MutationObserver(addButton).observe(document.body,{childList:true,subtree:true});document.getElementById('ks-code-close').onclick=()=>{data.files[data.active]=editor.value;save();modal.hidden=true};document.getElementById('ks-code-new').onclick=()=>{let p=prompt('Nama file, contoh: styles.css');if(p&&/^[A-Za-z0-9_./-]+\.[A-Za-z0-9]+$/.test(p)&&!p.includes('..')){data.files[p]='';data.active=p;save();render()}};document.getElementById('ks-code-folder').onclick=async()=>{if(!window.showDirectoryPicker){status.textContent='Browser ini tidak mendukung akses folder. Workspace tetap tersimpan lokal di browser; gunakan Chrome atau Edge untuk menulis folder langsung.';return}try{handle=await window.showDirectoryPicker({mode:'readwrite'});status.textContent='Folder lokal terhubung. Perubahan AI berikutnya otomatis ditulis ke folder ini.'}catch{}};task.onsubmit=async e=>{e.preventDefault();data.files[data.active]=editor.value;save();const prompt=document.getElementById('ks-code-prompt').value.trim();if(!prompt)return;status.textContent='AI 120B sedang membaca workspace dan membuat perubahan…';const button=task.querySelector('button');button.disabled=true;try{const r=await fetch('/api/assistant/code-workspace',{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json'},body:JSON.stringify({task:prompt,files:Object.entries(data.files).map(([path,content])=>({path,content}))})}),out=await r.json();if(!r.ok)throw Error(out.error||'Permintaan gagal');for(const item of out.files||[])await write(item.path,item.content);for(const path of out.delete||[])delete data.files[path];data.active=(out.files?.[0]?.path)||data.active;save();render();status.textContent=out.summary||'Perubahan selesai dibuat di perangkat ini.'}catch(err){status.textContent=err.message||'Code AI gagal'}finally{button.disabled=false}};render()})();