hanoman 0.9.26 → 0.9.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{d as Ee,q as X,r as Fe,h as L,i as O,K as ze,G as Me,j as e,L as Re,m as _e,x as Oe,Q as qe,w as Ke,g as ke,bb as fe,aX as Z,C as $e,R as Ge,X as Je,n as G,B as g,e as Q,f as Y,V as pe,D as Te,aI as ye,Z as te,bc as He,bd as Ue,be as We,bf as Ve,bg as Xe,bh as Qe,l as Ze,bi as Ye,a2 as ea}from"./index-BvFCEJud.js";import{R as l}from"./react-DfGhg7ZW.js";import{L as aa}from"./live-B2RFSX3l.js";import"./markdown-CWEY34jk.js";import{u as na,I as je,a as we,c as ie}from"./sched-lead-shared-0mpQqjza.js";import"./xterm-3VOAfa_q.js";/* empty css */const sa=5e3,K=20,be=400,ia={aktif:"aktif",jeda:"dijeda",mati:"mati"},ta=[{key:"semua",label:"Semua"},{key:"keputusan",label:"Keputusan"},{key:"rangkaian",label:"Rangkaian"}],la={berlaku:"ok",ditimpa:"warn",dibatalkan:"neutral",gagal:"err"},ra={menunggu:"warn",sebagian:"info",selesai:"ok",dibatalkan:"neutral"},da=new Set(["menunggu","sebagian"]),q=n=>({everyMin:String(n.everyMin),timeoutSec:String(n.timeoutSec),maxAutoAnswers:String(n.maxAutoAnswers),requireGreen:n.requireGreenBeforeIntegrate}),ca={everyMin:"5",timeoutSec:"600",maxAutoAnswers:"3",requireGreen:!0};function xe({total:n,page:o,onPage:i,unit:u}){const k=te(n,o,K);return e.jsx(ea,{page:k.page,pageCount:k.pageCount,total:n,from:k.from,to:k.to,onPage:i,unit:u})}function oa({page:n,pageCount:o,onPage:i}){return o<=1?null:e.jsxs("div",{className:"hn-lead-footer",children:[e.jsxs("span",{children:["Halaman ",n," dari ",o," · keputusan dan rangkaian"]}),e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",variant:"ghost","aria-label":"Sebelumnya",disabled:n<=1,onClick:()=>i(n-1),children:"Sebelumnya"}),e.jsx(g,{size:"sm",variant:"ghost","aria-label":"Berikutnya",disabled:n>=o,onClick:()=>i(n+1),children:"Berikutnya"})]})]})}function ua({sid:n,title:o,label:i,needsYou:u,onGoto:k,onAnswered:h,onError:t}){const[N,P]=l.useState(null),[A,C]=l.useState("idle"),[D,f]=l.useState([]),[w,E]=l.useState(!1);l.useEffect(()=>{if(!u)return;let d=!0;return C("loading"),Promise.resolve().then(()=>L.sessionDialog(n)).then(b=>{d&&(P(b),C(b&&b.dialog.options.length>0?"ready":"unavailable"))},()=>{d&&C("unavailable")}),()=>{d=!1}},[n,u]);async function F(d,b){if(N){E(!0);try{await L.answerSessionDialog(n,b?{screenHash:N.screenHash,choice:d[0]}:{screenHash:N.screenHash,choices:d}),f([]),h()}catch(I){t(O("menjawab sesi",I))}finally{E(!1)}}}const v=d=>f(b=>b.includes(d)?b.filter(I=>I!==d):[...b,d]),p=N==null?void 0:N.dialog;return e.jsxs("li",{className:"hn-lead-wait",children:[e.jsxs("div",{className:"hn-lead-wait-head",children:[e.jsx("span",{className:"hn-lead-wait-title",children:o}),e.jsx(G,{tone:u?"warn":"ok",size:"sm",children:i})]}),u&&A==="loading"&&e.jsx("p",{className:"hn-lead-note",children:"Membaca pertanyaannya…"}),u&&A==="unavailable"&&e.jsx("p",{className:"hn-lead-note",children:"Pertanyaan ini belum bisa dijawab dari sini. Jawab di Terminal."}),u&&A==="ready"&&p&&e.jsxs(e.Fragment,{children:[p.title&&e.jsx("p",{className:"hn-lead-wait-question",children:p.title}),p.multi?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"hn-lead-options-multi",role:"group","aria-label":p.title||"Pilihan jawaban",children:p.options.map(d=>e.jsx(ye,{checked:D.includes(d.n),label:d.label,disabled:w,onChange:()=>v(d.n)},d.n))}),e.jsx("div",{className:"hn-lead-wait-foot",children:e.jsx(g,{size:"sm",disabled:w||D.length===0,onClick:()=>void F(D,!1),children:"Kirim pilihan"})})]}):e.jsx("div",{className:"hn-lead-options",role:"group","aria-label":p.title||"Pilihan jawaban",children:p.options.map(d=>e.jsx(g,{size:"sm",variant:"secondary",disabled:w,onClick:()=>void F([d.n],!0),children:d.label},d.n))}),(p.freeIndex!=null||p.notes)&&e.jsx("p",{className:"hn-lead-note",children:"Jawaban bebas: jawab di Terminal."})]}),e.jsx("div",{className:"hn-lead-wait-foot",children:e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"terminal",onClick:k,children:"Buka di Terminal"})})]})}function ha({label:n,options:o,multi:i,value:u,onChange:k}){return i?e.jsx("div",{role:"group","aria-label":n,className:"hn-lead-options-multi",children:o.map(h=>e.jsx(ye,{checked:u.includes(h),label:h,onChange:()=>k(u.includes(h)?u.filter(t=>t!==h):[...u,h])},h))}):e.jsx(fe,{"aria-label":n,value:u[0]??"",onChange:h=>k([h]),children:o.map(h=>e.jsx(Z,{value:h,label:h},h))})}function ma({d:n,projectName:o,onOverride:i,onCancel:u,busyId:k,ask:h}){var M;const[t,N]=l.useState(!1),[P,A]=l.useState(""),[C,D]=l.useState([]),f=(n.choices??[]).length>0?n.choices:n.choiceIndex!=null&&n.choice?[{index:n.choiceIndex,option:n.choice}]:[],w=n.options??[],E=((M=n.select)==null?void 0:M.mode)==="multi",F=[o(n.projectId),n.specId].filter(Boolean).join(" · "),v=n.action!=="none"?He[n.action]:void 0,p=n.question.length>be?`${n.question.slice(0,be)}…`:n.question,d=k===n.id,b=()=>{N(!1),A(""),D([])},I=f.length?f.map(y=>y.option).join(" · "):n.answer||"tidak ada jawaban",z=P.trim()||C.join("; "),J=async()=>{let y=!1;await h({title:"Ubah jawaban keputusan ini?",eyebrow:"lead · ubah jawaban",impact:[`Jawaban sekarang: ${I}`,`Jadi: ${z}`],confirmLabel:"Ubah jawaban",icon:"edit-3",tone:"default",run:async()=>{y=await i(n.id,z,C)}}),y&&b()};return e.jsxs("li",{className:"hn-lead-item",children:[e.jsxs("div",{className:"hn-lead-item-head",children:[e.jsx(G,{tone:la[n.status]??"neutral",size:"sm",children:Ue[n.status]??n.status}),n.weighty&&e.jsx(G,{tone:"warn",size:"sm",children:"berbobot"}),e.jsx("span",{className:"hn-lead-item-time",children:we(n.createdAt)})]}),e.jsx("div",{className:"hn-lead-item-question",children:p}),e.jsx("div",{className:"hn-lead-item-answer",children:f.length?f.map(y=>y.option).join(" · "):n.answer||e.jsx("em",{children:"tidak ada jawaban"})}),n.reason&&e.jsx("div",{className:"hn-lead-item-reason",children:n.reason}),e.jsxs("div",{className:"hn-lead-item-meta",children:[e.jsx("span",{children:We[n.kind]??n.kind}),e.jsx("span",{children:Ve[n.gate]??n.gate}),e.jsx("span",{children:Xe[n.confidence]??n.confidence}),f.length>0&&w.length>0&&e.jsx("span",{children:f.length>1?`${f.length} dari ${w.length} opsi`:`opsi ${f[0].index} dari ${w.length}`}),(n.missing??[]).length>0&&e.jsx("span",{children:"kurang konteks"}),e.jsxs("span",{children:[F,v?` · ${v}`:""]})]}),(n.missing??[]).length>0&&e.jsxs("div",{className:"hn-lead-item-reason",children:["Yang kurang: ",n.missing.join(" · ")]}),n.refs.length>0&&e.jsx("div",{className:"hn-lead-refs",children:n.refs.map(y=>e.jsx("span",{className:"hn-lead-ref",children:y},y))}),n.status==="berlaku"&&!t&&e.jsx("div",{className:"hn-lead-item-foot",children:e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"edit-3",onClick:()=>N(!0),children:"Ubah jawaban"}),e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"x-circle",disabled:d,onClick:()=>u(n),children:"Batalkan"})]})}),t&&e.jsxs("div",{className:"hn-lead-change",children:[w.length>0&&e.jsx(ha,{label:`Pilihan jawaban${n.specId?` untuk ${n.specId}`:""}`,options:w,multi:E,value:C,onChange:D}),e.jsxs("div",{className:"hn-lead-change-row",children:[e.jsx(Y,{className:"hn-lead-change-input","aria-label":`Jawaban kamu${n.specId?` untuk ${n.specId}`:""}`,placeholder:"mis. pilih opsi 2, pakai Node 22",value:P,onChange:y=>A(y.target.value)}),e.jsx(g,{size:"sm",variant:"ghost",disabled:d,onClick:b,children:"Batal"}),e.jsx(g,{size:"sm",leftIcon:"check",disabled:!P.trim()&&C.length===0||d,onClick:()=>void J(),children:"Kirim jawaban"})]})]})]})}function ga({f:n,busyId:o,onClose:i}){return e.jsxs("li",{className:"hn-lead-item",children:[e.jsxs("div",{className:"hn-lead-item-head",children:[e.jsx(G,{tone:ra[n.status]??"neutral",size:"sm",children:Qe[n.status]??n.status}),e.jsx("span",{className:"hn-lead-item-time",children:we(n.openedAt)})]}),e.jsx("div",{className:"hn-lead-item-answer",children:n.title}),e.jsxs("div",{className:"hn-lead-item-meta",children:[e.jsxs("span",{children:[n.steps," langkah"]}),n.closeReason&&e.jsx("span",{children:Ze(Ye,n.closeReason)})]}),da.has(n.status)&&e.jsx("div",{className:"hn-lead-item-foot",children:e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",leftIcon:"check",disabled:o===n.id,onClick:()=>i(n,"submit"),children:"Kirim rangkaian"}),e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"x-circle",disabled:o===n.id,onClick:()=>i(n,"cancel"),children:"Batalkan rangkaian"})]})})]})}function va({projects:n,onProjectChanged:o,onToast:i,onGotoTerminal:u}){var ge;const{confirm:k,dialog:h}=Ee(),[t,N]=l.useState(null),[P,A]=l.useState([]),[C,D]=l.useState([]),[f,w]=l.useState(!1),[E,F]=l.useState(0),[v,p]=X("lead","decPage",1,pe),[d,b]=l.useState(0),[I,z]=X("lead","flowPage",1,pe),[J,M]=l.useState("loading"),[y,ee]=l.useState(null),[R,le]=l.useState(!1),[T,B]=l.useState(null),[S,ae]=X("lead","filter","all",Te),[_,ve]=X("lead","kind","semua",Fe("semua","keputusan","rangkaian")),H=l.useRef(!1),U=l.useCallback(a=>{var s;return((s=n.find(r=>r.id===a))==null?void 0:s.name)??"Project lain"},[n]),m=l.useCallback((a=!1)=>{!a&&!H.current&&M("loading"),Promise.all([L.getLeadStatus(),L.getLeadDecisions({projectId:S==="all"?void 0:S,page:v,limit:K}),L.getLeadFlows({projectId:S==="all"?void 0:S,page:I,limit:K}).catch(()=>null)]).then(([s,r,x])=>{H.current=!0,N(s),A(r.items??[]),F(r.total??0),x?(D(x.items??[]),b(x.total??0),w(!1)):w(!0),ee(null),M("ready")}).catch(s=>{if(!H.current){M("error");return}a||ee(O("memuat keputusan",s))})},[S,v,I]);l.useEffect(()=>{m()},[m]),ze(S,()=>{p(1),z(1)}),Me({topic:"lead",params:{projectId:S==="all"?void 0:S,decPage:v,flowPage:I,limit:K},apply:a=>{H.current=!0,N(a.status),A(a.decisions.items),F(a.decisions.total),D(a.flows.items),b(a.flows.total),w(!1),ee(null),M("ready")},refetch:()=>m(!0),pollMs:sa});const j=(t==null?void 0:t.config)??null,c=na(j?q(j):ca),ne=c.dirty,$=l.useCallback(async(a,s=!1)=>{le(!0);try{return await L.putLeadConfig(a),s||i("Setelan lead tersimpan","ok","save"),m(!0),!0}catch(r){return i(O("menyimpan setelan lead",r),"err","x-circle"),!1}finally{le(!1)}},[m,i]),Ne=async()=>{if(!j)return;const a={...j,everyMin:ie(c.draft.everyMin,1,1440,j.everyMin),timeoutSec:ie(c.draft.timeoutSec,10,900,j.timeoutSec),maxAutoAnswers:ie(c.draft.maxAutoAnswers,1,20,j.maxAutoAnswers),requireGreenBeforeIntegrate:c.draft.requireGreen};if(JSON.stringify(q(a))===JSON.stringify(q(j))){c.setDraft(q(j));return}c.setDraft(q(a)),await $(a)},re=l.useCallback(async(a,s)=>{B(a);try{await L.updateProject(a,{leadOptIn:s}),await o(a),m(!0),i(s?"Project diserahkan ke lead":"Project ditarik dari lead","ok")}catch(r){i(O("mengubah lead untuk project",r),"err","x-circle")}finally{B(null)}},[m,o,i]),de=l.useCallback(async(a,s)=>{if(!t)return;const r=new Set(t.config.pausedProjects);s?r.add(a):r.delete(a),await $({...t.config,pausedProjects:[...r]},!0)},[t,$]),Se=l.useCallback(async(a,s,r=[])=>{B(a);try{const x=await L.overrideLeadDecision(a,s,"",r);return i(x.delivered?"Jawaban kamu dikirim ke sesi":"Keputusan diubah","ok","check"),m(!0),!0}catch(x){return i(O("mengubah keputusan",x),"err","x-circle"),!1}finally{B(null)}},[m,i]),ce=l.useCallback(async(a,s)=>{B(a);try{await(s==="submit"?L.submitLeadFlow(a):L.cancelLeadFlow(a)),i(s==="submit"?"Rangkaian dikirim":"Rangkaian ditutup tanpa dikirim","ok","check"),m(!0)}catch(r){i(O("menutup rangkaian",r),"err","x-circle")}finally{B(null)}},[m,i]),Le=l.useCallback(async a=>{B(a);try{await L.cancelLeadDecision(a),i("Keputusan dibatalkan","ok"),m(!0)}catch(s){i(O("membatalkan keputusan",s),"err","x-circle")}finally{B(null)}},[m,i]),Ce=(a,s)=>{k(s==="submit"?{title:"Kirim rangkaian ini?",eyebrow:"lead · rangkaian",message:"Semua jawaban yang sudah terkumpul dikirim ke sesi peminta. Rangkaian lalu ditutup dan tidak bisa ditambah lagi.",confirmLabel:"Kirim rangkaian",icon:"check",tone:"default",run:()=>ce(a.id,"submit")}:{title:"Batalkan rangkaian ini?",eyebrow:"lead · rangkaian",message:"Rangkaian ditutup tanpa dikirim. Jawaban yang sudah terkumpul tidak sampai ke sesi peminta.",confirmLabel:"Tutup tanpa mengirim",icon:"x-circle",tone:"danger",run:()=>ce(a.id,"cancel")})},Ie=a=>{k({title:"Batalkan keputusan ini?",eyebrow:"lead · keputusan",message:"Keputusan ini ditandai dibatalkan dan tidak lagi berlaku.",confirmLabel:"Batalkan keputusan",icon:"x-circle",tone:"danger",run:()=>Le(a.id)})},Ae=a=>{if(j){if(a==="mati"){k({title:"Matikan lead?",eyebrow:"lead · kendali",message:"Lead berhenti memutuskan untuk semua project. Sesi yang sudah berjalan tidak diubah, dan pertanyaan yang menunggu tetap menunggu kamu.",confirmLabel:"Matikan lead",icon:"ban",tone:"danger",run:()=>$({...j,enabled:!1,paused:!1}).then(()=>{})});return}$({...j,enabled:!0,paused:a==="jeda"})}};if(J==="loading")return e.jsx(Re,{rows:4,label:"Memuat lead…"});if(J==="error"||!t)return e.jsx(_e,{kind:"error",hint:"Gagal memuat status lead.",action:()=>m(),actionLabel:"Coba lagi"});const oe=t.config.enabled?t.config.paused?"jeda":"aktif":"mati",ue=new Set(t.projects.map(a=>a.projectId)),W=t.waiting,he=new Set(t.deciding),se=new Set(t.queued??[]),V=t.gate??{inFlight:0,queued:0,capacity:1},De=a=>{const s=(t.queue??[]).find(x=>x.sessionId===a);if(s)return[U(s.projectId),s.specId].filter(Boolean).join(" · ");const r=P.find(x=>x.sessionId===a);return r?[U(r.projectId),r.specId].filter(Boolean).join(" · "):"Sesi (rincian ada di riwayat)"},me=[..._!=="rangkaian"?P.map(a=>({key:`d:${a.id}`,at:a.createdAt,d:a})):[],..._!=="keputusan"&&!f?C.map(a=>({key:`f:${a.id}`,at:a.openedAt,f:a})):[]].sort((a,s)=>Date.parse(s.at)-Date.parse(a.at)),Pe=_==="semua"?e.jsx(oa,{page:v,pageCount:Math.max(te(E,v,K).pageCount,te(d,v,K).pageCount),onPage:a=>{p(a),z(a)}}):_==="keputusan"?e.jsx(xe,{total:E,page:v,onPage:p,unit:"keputusan"}):e.jsx(xe,{total:d,page:I,onPage:z,unit:"rangkaian"}),Be=S==="all"?[]:[{key:"project",label:`Project: ${U(S)}`,onRemove:()=>ae("all")}];return e.jsxs("div",{className:"hn-lead",children:[e.jsxs("p",{className:"hn-lead-summary",children:["Lead ",ia[oe]," · ",W.length," menunggu kamu · ",se.size," antre"]}),e.jsxs("div",{className:"hn-lead-layout",children:[e.jsxs("div",{className:"hn-lead-main",children:[e.jsxs("section",{className:"hn-lead-section","aria-labelledby":"lead-menunggu-h",children:[e.jsxs("h2",{id:"lead-menunggu-h",className:"hn-lead-h",children:["Menunggu kamu (",W.length,")"]}),V.queued>0&&e.jsxs("p",{className:"hn-lead-note",children:["Antrean keputusan penuh: ",V.inFlight," dari ",V.capacity," sedang diputuskan, ",V.queued," menunggu giliran."]}),W.length===0?e.jsx("p",{className:"hn-lead-note",children:"Tidak ada sesi yang menunggu keputusanmu. Lead menangani sisanya."}):e.jsx("ul",{className:"hn-lead-waits",children:W.map(a=>{const s=he.has(a)?"Sedang diputuskan":se.has(a)?"Antre giliran":"Menunggu kamu",r=!he.has(a)&&!se.has(a);return e.jsx(ua,{sid:a,title:De(a),label:s,needsYou:r,onGoto:()=>u(a),onAnswered:()=>{i("Jawaban kamu dikirim ke sesi","ok","check"),m(!0)},onError:x=>i(x,"err","x-circle")},a)})})]}),e.jsxs("section",{className:"hn-lead-section","aria-labelledby":"lead-riwayat-h",children:[e.jsx("h2",{id:"lead-riwayat-h",className:"hn-lead-h",children:"Riwayat"}),e.jsx("div",{className:"hn-lead-chips",role:"group","aria-label":"Jenis riwayat",children:ta.map(a=>e.jsx("button",{type:"button",className:"hn-lead-chip","aria-pressed":_===a.key,onClick:()=>{a.key==="semua"&&z(v),ve(a.key)},children:a.label},a.key))}),e.jsx(Oe,{label:"Filter riwayat",chips:Be,filters:e.jsx(Ke,{gap:3,children:e.jsx(ke,{size:"sm",value:S,"aria-label":"saring project",onChange:a=>ae(a.target.value),options:[{value:"all",label:"semua project"},...n.map(a=>({value:a.id,label:a.name}))]})}),filtersLabel:"Project",onReset:()=>ae("all"),resetLabel:"Hapus filter",actions:e.jsxs(e.Fragment,{children:[e.jsx(qe,{screen:"lead",active:S==="all"?0:1}),e.jsx(aa,{})]})}),y&&e.jsx(je,{message:y,onRetry:()=>m()}),f&&_!=="keputusan"&&e.jsx(je,{message:"Gagal memuat rangkaian keputusan.",onRetry:()=>m()}),me.length===0?e.jsx("p",{className:"hn-lead-note",children:_==="rangkaian"?"Belum ada rangkaian. Satu rangkaian adalah satu urusan: beberapa pertanyaan berurutan sampai kamu kirim.":"Belum ada keputusan. Lead menulis satu baris di sini setiap kali ia memutuskan."}):e.jsx("ul",{className:"hn-lead-timeline","aria-label":"Riwayat keputusan dan rangkaian",children:me.map(a=>a.d?e.jsx(ma,{d:a.d,projectName:U,onOverride:Se,onCancel:Ie,busyId:T,ask:k},a.key):e.jsx(ga,{f:a.f,busyId:T,onClose:Ce},a.key))}),Pe]})]}),e.jsxs("aside",{className:"hn-lead-side","aria-label":"Kendali lead",children:[e.jsxs("section",{className:"hn-lead-section","aria-labelledby":"lead-kendali-h",children:[e.jsx("h2",{id:"lead-kendali-h",className:"hn-lead-h",children:"Kendali"}),e.jsx("div",{className:"hn-lead-mode",children:e.jsxs(fe,{label:"Mode lead",value:oe,onChange:a=>Ae(a),children:[e.jsx(Z,{value:"aktif",label:"Aktif",description:"Lead memutuskan untuk project yang diurusnya.",disabled:R}),e.jsx(Z,{value:"jeda",label:"Jeda",description:"Keputusan baru berhenti. Sesi yang berjalan tidak diubah.",disabled:R}),e.jsx(Z,{value:"mati",label:"Mati",description:"Lead berhenti total. Pertanyaan yang menunggu tetap menunggu kamu.",disabled:R})]})}),e.jsx($e,{tone:"info",title:"Dikunci secara teknis",children:"Produksi, VPS, dan penghapusan data tetap terkunci untuk lead, apa pun setelannya."})]}),e.jsxs("details",{className:"hn-lead-disclosure",children:[e.jsxs("summary",{children:["Project yang dipimpin · ",ue.size," dari ",n.length," diurus lead"]}),e.jsx("p",{className:"hn-lead-hint",children:"Lead hanya menyentuh project yang diserahkan kepadanya. Default: tidak diserahkan."}),n.length===0?e.jsx("p",{className:"hn-lead-note",children:"Belum ada project."}):e.jsx(Ge,{label:"Project yang dipimpin lead",children:n.map(a=>{const s=t.projects.find(x=>x.projectId===a.id),r=ue.has(a.id);return e.jsxs(Je,{actions:e.jsxs(e.Fragment,{children:[r&&(s!=null&&s.paused?e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"play",disabled:R,onClick:()=>de(a.id,!1),children:"Lanjutkan"}):e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"pause",disabled:R,onClick:()=>de(a.id,!0),children:"Jeda"})),r?e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"ban",disabled:T===a.id,onClick:()=>re(a.id,!1),children:"Tarik dari lead"}):e.jsx(g,{size:"sm",leftIcon:"check",disabled:T===a.id,onClick:()=>re(a.id,!0),children:"Serahkan ke lead"})]}),children:[e.jsx("span",{className:"hn-lead-project-name",children:a.name}),s&&e.jsxs("span",{className:"hn-lead-project-meta",children:[s.decisions24h," keputusan 24 jam terakhir · ",s.openSessions," sesi terbuka"]}),e.jsx(G,{tone:r?s!=null&&s.paused?"warn":"ok":"neutral",size:"sm",children:r?s!=null&&s.paused?"dijeda":"diurus lead":"tidak diurus"})]},a.id)})})]}),e.jsxs("details",{className:"hn-lead-disclosure",children:[e.jsx("summary",{children:"Pengaturan lead"}),e.jsxs("div",{className:"hn-lead-settings",children:[e.jsxs("div",{className:"hn-lead-settings-grid",children:[e.jsx(Q,{label:"Lead memeriksa tiap (menit)",hint:"1–1440. Berlaku setelah Simpan.",children:e.jsx(Y,{type:"number",min:1,max:1440,"aria-label":"lead memeriksa tiap (menit)",placeholder:"mis. 5",value:c.draft.everyMin,disabled:!j,onChange:a=>c.setDraft({...c.draft,everyMin:a.target.value})})}),e.jsx(Q,{label:"Batas waktu keputusan (detik)",hint:"10–900. Lewat dari ini, keputusan gagal.",children:e.jsx(Y,{type:"number",min:10,max:900,"aria-label":"batas waktu keputusan (detik)",placeholder:"mis. 600",value:c.draft.timeoutSec,disabled:!j,onChange:a=>c.setDraft({...c.draft,timeoutSec:a.target.value})})}),e.jsx(Q,{label:"Jawaban otomatis per sesi (maks)",hint:"1–20. Setelah batas, sesi diserahkan ke kamu.",children:e.jsx(Y,{type:"number",min:1,max:20,"aria-label":"maksimum jawaban otomatis per sesi",placeholder:"mis. 3",value:c.draft.maxAutoAnswers,disabled:!j,onChange:a=>c.setDraft({...c.draft,maxAutoAnswers:a.target.value})})}),e.jsx(Q,{label:"Syarat integrasi ke main",hint:"Berlaku untuk integrasi yang diputuskan lead.",children:e.jsx(ke,{size:"sm","aria-label":"syarat integrasi ke main",value:c.draft.requireGreen?"wajib":"bebas",onChange:a=>c.setDraft({...c.draft,requireGreen:a.target.value==="wajib"}),options:[{value:"wajib",label:"plan harus tuntas dulu"},{value:"bebas",label:"tanpa syarat"}]})})]}),e.jsxs("div",{"data-testid":"lead-engine-line",className:"hn-lead-note",children:["Model lead: ",(ge=t.config.engine)!=null&&ge.enabled?e.jsxs(e.Fragment,{children:[t.config.engine.agent==="codex"?"Codex CLI":"Claude Code"," · ",e.jsx("code",{children:t.config.engine.model})," · ",e.jsx("code",{children:t.config.engine.effort})]}):e.jsx(e.Fragment,{children:"ikut default global · atur di Settings → Model sesi"})]}),e.jsxs("div",{className:"hn-lead-footer",children:[e.jsx("span",{role:"status","aria-live":"polite",children:ne?"Ada perubahan yang belum disimpan.":""}),e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",variant:"ghost",disabled:!ne||R,onClick:()=>c.setDraft(q(t.config)),children:"Batal"}),e.jsx(g,{size:"sm",leftIcon:"check",disabled:!ne||R||!j,onClick:()=>void Ne(),children:"Simpan pengaturan"})]})]})]})]})]})]}),h]})}export{va as LeadScreen};
1
+ import{d as Ee,q as X,r as Fe,h as L,i as O,K as ze,G as Me,j as e,L as Re,m as _e,x as Oe,Q as qe,w as Ke,g as ke,bb as fe,aX as Z,C as $e,R as Ge,X as Je,n as G,B as g,e as Q,f as Y,V as pe,D as Te,aI as ye,Z as te,bc as He,bd as Ue,be as We,bf as Ve,bg as Xe,bh as Qe,l as Ze,bi as Ye,a2 as ea}from"./index-Av-RfHXX.js";import{R as l}from"./react-DfGhg7ZW.js";import{L as aa}from"./live-Bfx0Oehi.js";import"./markdown-CWEY34jk.js";import{u as na,I as je,a as we,c as ie}from"./sched-lead-shared-DJn2D3VE.js";import"./xterm-3VOAfa_q.js";/* empty css */const sa=5e3,K=20,be=400,ia={aktif:"aktif",jeda:"dijeda",mati:"mati"},ta=[{key:"semua",label:"Semua"},{key:"keputusan",label:"Keputusan"},{key:"rangkaian",label:"Rangkaian"}],la={berlaku:"ok",ditimpa:"warn",dibatalkan:"neutral",gagal:"err"},ra={menunggu:"warn",sebagian:"info",selesai:"ok",dibatalkan:"neutral"},da=new Set(["menunggu","sebagian"]),q=n=>({everyMin:String(n.everyMin),timeoutSec:String(n.timeoutSec),maxAutoAnswers:String(n.maxAutoAnswers),requireGreen:n.requireGreenBeforeIntegrate}),ca={everyMin:"5",timeoutSec:"600",maxAutoAnswers:"3",requireGreen:!0};function xe({total:n,page:o,onPage:i,unit:u}){const k=te(n,o,K);return e.jsx(ea,{page:k.page,pageCount:k.pageCount,total:n,from:k.from,to:k.to,onPage:i,unit:u})}function oa({page:n,pageCount:o,onPage:i}){return o<=1?null:e.jsxs("div",{className:"hn-lead-footer",children:[e.jsxs("span",{children:["Halaman ",n," dari ",o," · keputusan dan rangkaian"]}),e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",variant:"ghost","aria-label":"Sebelumnya",disabled:n<=1,onClick:()=>i(n-1),children:"Sebelumnya"}),e.jsx(g,{size:"sm",variant:"ghost","aria-label":"Berikutnya",disabled:n>=o,onClick:()=>i(n+1),children:"Berikutnya"})]})]})}function ua({sid:n,title:o,label:i,needsYou:u,onGoto:k,onAnswered:h,onError:t}){const[N,P]=l.useState(null),[A,C]=l.useState("idle"),[D,f]=l.useState([]),[w,E]=l.useState(!1);l.useEffect(()=>{if(!u)return;let d=!0;return C("loading"),Promise.resolve().then(()=>L.sessionDialog(n)).then(b=>{d&&(P(b),C(b&&b.dialog.options.length>0?"ready":"unavailable"))},()=>{d&&C("unavailable")}),()=>{d=!1}},[n,u]);async function F(d,b){if(N){E(!0);try{await L.answerSessionDialog(n,b?{screenHash:N.screenHash,choice:d[0]}:{screenHash:N.screenHash,choices:d}),f([]),h()}catch(I){t(O("menjawab sesi",I))}finally{E(!1)}}}const v=d=>f(b=>b.includes(d)?b.filter(I=>I!==d):[...b,d]),p=N==null?void 0:N.dialog;return e.jsxs("li",{className:"hn-lead-wait",children:[e.jsxs("div",{className:"hn-lead-wait-head",children:[e.jsx("span",{className:"hn-lead-wait-title",children:o}),e.jsx(G,{tone:u?"warn":"ok",size:"sm",children:i})]}),u&&A==="loading"&&e.jsx("p",{className:"hn-lead-note",children:"Membaca pertanyaannya…"}),u&&A==="unavailable"&&e.jsx("p",{className:"hn-lead-note",children:"Pertanyaan ini belum bisa dijawab dari sini. Jawab di Terminal."}),u&&A==="ready"&&p&&e.jsxs(e.Fragment,{children:[p.title&&e.jsx("p",{className:"hn-lead-wait-question",children:p.title}),p.multi?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"hn-lead-options-multi",role:"group","aria-label":p.title||"Pilihan jawaban",children:p.options.map(d=>e.jsx(ye,{checked:D.includes(d.n),label:d.label,disabled:w,onChange:()=>v(d.n)},d.n))}),e.jsx("div",{className:"hn-lead-wait-foot",children:e.jsx(g,{size:"sm",disabled:w||D.length===0,onClick:()=>void F(D,!1),children:"Kirim pilihan"})})]}):e.jsx("div",{className:"hn-lead-options",role:"group","aria-label":p.title||"Pilihan jawaban",children:p.options.map(d=>e.jsx(g,{size:"sm",variant:"secondary",disabled:w,onClick:()=>void F([d.n],!0),children:d.label},d.n))}),(p.freeIndex!=null||p.notes)&&e.jsx("p",{className:"hn-lead-note",children:"Jawaban bebas: jawab di Terminal."})]}),e.jsx("div",{className:"hn-lead-wait-foot",children:e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"terminal",onClick:k,children:"Buka di Terminal"})})]})}function ha({label:n,options:o,multi:i,value:u,onChange:k}){return i?e.jsx("div",{role:"group","aria-label":n,className:"hn-lead-options-multi",children:o.map(h=>e.jsx(ye,{checked:u.includes(h),label:h,onChange:()=>k(u.includes(h)?u.filter(t=>t!==h):[...u,h])},h))}):e.jsx(fe,{"aria-label":n,value:u[0]??"",onChange:h=>k([h]),children:o.map(h=>e.jsx(Z,{value:h,label:h},h))})}function ma({d:n,projectName:o,onOverride:i,onCancel:u,busyId:k,ask:h}){var M;const[t,N]=l.useState(!1),[P,A]=l.useState(""),[C,D]=l.useState([]),f=(n.choices??[]).length>0?n.choices:n.choiceIndex!=null&&n.choice?[{index:n.choiceIndex,option:n.choice}]:[],w=n.options??[],E=((M=n.select)==null?void 0:M.mode)==="multi",F=[o(n.projectId),n.specId].filter(Boolean).join(" · "),v=n.action!=="none"?He[n.action]:void 0,p=n.question.length>be?`${n.question.slice(0,be)}…`:n.question,d=k===n.id,b=()=>{N(!1),A(""),D([])},I=f.length?f.map(y=>y.option).join(" · "):n.answer||"tidak ada jawaban",z=P.trim()||C.join("; "),J=async()=>{let y=!1;await h({title:"Ubah jawaban keputusan ini?",eyebrow:"lead · ubah jawaban",impact:[`Jawaban sekarang: ${I}`,`Jadi: ${z}`],confirmLabel:"Ubah jawaban",icon:"edit-3",tone:"default",run:async()=>{y=await i(n.id,z,C)}}),y&&b()};return e.jsxs("li",{className:"hn-lead-item",children:[e.jsxs("div",{className:"hn-lead-item-head",children:[e.jsx(G,{tone:la[n.status]??"neutral",size:"sm",children:Ue[n.status]??n.status}),n.weighty&&e.jsx(G,{tone:"warn",size:"sm",children:"berbobot"}),e.jsx("span",{className:"hn-lead-item-time",children:we(n.createdAt)})]}),e.jsx("div",{className:"hn-lead-item-question",children:p}),e.jsx("div",{className:"hn-lead-item-answer",children:f.length?f.map(y=>y.option).join(" · "):n.answer||e.jsx("em",{children:"tidak ada jawaban"})}),n.reason&&e.jsx("div",{className:"hn-lead-item-reason",children:n.reason}),e.jsxs("div",{className:"hn-lead-item-meta",children:[e.jsx("span",{children:We[n.kind]??n.kind}),e.jsx("span",{children:Ve[n.gate]??n.gate}),e.jsx("span",{children:Xe[n.confidence]??n.confidence}),f.length>0&&w.length>0&&e.jsx("span",{children:f.length>1?`${f.length} dari ${w.length} opsi`:`opsi ${f[0].index} dari ${w.length}`}),(n.missing??[]).length>0&&e.jsx("span",{children:"kurang konteks"}),e.jsxs("span",{children:[F,v?` · ${v}`:""]})]}),(n.missing??[]).length>0&&e.jsxs("div",{className:"hn-lead-item-reason",children:["Yang kurang: ",n.missing.join(" · ")]}),n.refs.length>0&&e.jsx("div",{className:"hn-lead-refs",children:n.refs.map(y=>e.jsx("span",{className:"hn-lead-ref",children:y},y))}),n.status==="berlaku"&&!t&&e.jsx("div",{className:"hn-lead-item-foot",children:e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"edit-3",onClick:()=>N(!0),children:"Ubah jawaban"}),e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"x-circle",disabled:d,onClick:()=>u(n),children:"Batalkan"})]})}),t&&e.jsxs("div",{className:"hn-lead-change",children:[w.length>0&&e.jsx(ha,{label:`Pilihan jawaban${n.specId?` untuk ${n.specId}`:""}`,options:w,multi:E,value:C,onChange:D}),e.jsxs("div",{className:"hn-lead-change-row",children:[e.jsx(Y,{className:"hn-lead-change-input","aria-label":`Jawaban kamu${n.specId?` untuk ${n.specId}`:""}`,placeholder:"mis. pilih opsi 2, pakai Node 22",value:P,onChange:y=>A(y.target.value)}),e.jsx(g,{size:"sm",variant:"ghost",disabled:d,onClick:b,children:"Batal"}),e.jsx(g,{size:"sm",leftIcon:"check",disabled:!P.trim()&&C.length===0||d,onClick:()=>void J(),children:"Kirim jawaban"})]})]})]})}function ga({f:n,busyId:o,onClose:i}){return e.jsxs("li",{className:"hn-lead-item",children:[e.jsxs("div",{className:"hn-lead-item-head",children:[e.jsx(G,{tone:ra[n.status]??"neutral",size:"sm",children:Qe[n.status]??n.status}),e.jsx("span",{className:"hn-lead-item-time",children:we(n.openedAt)})]}),e.jsx("div",{className:"hn-lead-item-answer",children:n.title}),e.jsxs("div",{className:"hn-lead-item-meta",children:[e.jsxs("span",{children:[n.steps," langkah"]}),n.closeReason&&e.jsx("span",{children:Ze(Ye,n.closeReason)})]}),da.has(n.status)&&e.jsx("div",{className:"hn-lead-item-foot",children:e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",leftIcon:"check",disabled:o===n.id,onClick:()=>i(n,"submit"),children:"Kirim rangkaian"}),e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"x-circle",disabled:o===n.id,onClick:()=>i(n,"cancel"),children:"Batalkan rangkaian"})]})})]})}function va({projects:n,onProjectChanged:o,onToast:i,onGotoTerminal:u}){var ge;const{confirm:k,dialog:h}=Ee(),[t,N]=l.useState(null),[P,A]=l.useState([]),[C,D]=l.useState([]),[f,w]=l.useState(!1),[E,F]=l.useState(0),[v,p]=X("lead","decPage",1,pe),[d,b]=l.useState(0),[I,z]=X("lead","flowPage",1,pe),[J,M]=l.useState("loading"),[y,ee]=l.useState(null),[R,le]=l.useState(!1),[T,B]=l.useState(null),[S,ae]=X("lead","filter","all",Te),[_,ve]=X("lead","kind","semua",Fe("semua","keputusan","rangkaian")),H=l.useRef(!1),U=l.useCallback(a=>{var s;return((s=n.find(r=>r.id===a))==null?void 0:s.name)??"Project lain"},[n]),m=l.useCallback((a=!1)=>{!a&&!H.current&&M("loading"),Promise.all([L.getLeadStatus(),L.getLeadDecisions({projectId:S==="all"?void 0:S,page:v,limit:K}),L.getLeadFlows({projectId:S==="all"?void 0:S,page:I,limit:K}).catch(()=>null)]).then(([s,r,x])=>{H.current=!0,N(s),A(r.items??[]),F(r.total??0),x?(D(x.items??[]),b(x.total??0),w(!1)):w(!0),ee(null),M("ready")}).catch(s=>{if(!H.current){M("error");return}a||ee(O("memuat keputusan",s))})},[S,v,I]);l.useEffect(()=>{m()},[m]),ze(S,()=>{p(1),z(1)}),Me({topic:"lead",params:{projectId:S==="all"?void 0:S,decPage:v,flowPage:I,limit:K},apply:a=>{H.current=!0,N(a.status),A(a.decisions.items),F(a.decisions.total),D(a.flows.items),b(a.flows.total),w(!1),ee(null),M("ready")},refetch:()=>m(!0),pollMs:sa});const j=(t==null?void 0:t.config)??null,c=na(j?q(j):ca),ne=c.dirty,$=l.useCallback(async(a,s=!1)=>{le(!0);try{return await L.putLeadConfig(a),s||i("Setelan lead tersimpan","ok","save"),m(!0),!0}catch(r){return i(O("menyimpan setelan lead",r),"err","x-circle"),!1}finally{le(!1)}},[m,i]),Ne=async()=>{if(!j)return;const a={...j,everyMin:ie(c.draft.everyMin,1,1440,j.everyMin),timeoutSec:ie(c.draft.timeoutSec,10,900,j.timeoutSec),maxAutoAnswers:ie(c.draft.maxAutoAnswers,1,20,j.maxAutoAnswers),requireGreenBeforeIntegrate:c.draft.requireGreen};if(JSON.stringify(q(a))===JSON.stringify(q(j))){c.setDraft(q(j));return}c.setDraft(q(a)),await $(a)},re=l.useCallback(async(a,s)=>{B(a);try{await L.updateProject(a,{leadOptIn:s}),await o(a),m(!0),i(s?"Project diserahkan ke lead":"Project ditarik dari lead","ok")}catch(r){i(O("mengubah lead untuk project",r),"err","x-circle")}finally{B(null)}},[m,o,i]),de=l.useCallback(async(a,s)=>{if(!t)return;const r=new Set(t.config.pausedProjects);s?r.add(a):r.delete(a),await $({...t.config,pausedProjects:[...r]},!0)},[t,$]),Se=l.useCallback(async(a,s,r=[])=>{B(a);try{const x=await L.overrideLeadDecision(a,s,"",r);return i(x.delivered?"Jawaban kamu dikirim ke sesi":"Keputusan diubah","ok","check"),m(!0),!0}catch(x){return i(O("mengubah keputusan",x),"err","x-circle"),!1}finally{B(null)}},[m,i]),ce=l.useCallback(async(a,s)=>{B(a);try{await(s==="submit"?L.submitLeadFlow(a):L.cancelLeadFlow(a)),i(s==="submit"?"Rangkaian dikirim":"Rangkaian ditutup tanpa dikirim","ok","check"),m(!0)}catch(r){i(O("menutup rangkaian",r),"err","x-circle")}finally{B(null)}},[m,i]),Le=l.useCallback(async a=>{B(a);try{await L.cancelLeadDecision(a),i("Keputusan dibatalkan","ok"),m(!0)}catch(s){i(O("membatalkan keputusan",s),"err","x-circle")}finally{B(null)}},[m,i]),Ce=(a,s)=>{k(s==="submit"?{title:"Kirim rangkaian ini?",eyebrow:"lead · rangkaian",message:"Semua jawaban yang sudah terkumpul dikirim ke sesi peminta. Rangkaian lalu ditutup dan tidak bisa ditambah lagi.",confirmLabel:"Kirim rangkaian",icon:"check",tone:"default",run:()=>ce(a.id,"submit")}:{title:"Batalkan rangkaian ini?",eyebrow:"lead · rangkaian",message:"Rangkaian ditutup tanpa dikirim. Jawaban yang sudah terkumpul tidak sampai ke sesi peminta.",confirmLabel:"Tutup tanpa mengirim",icon:"x-circle",tone:"danger",run:()=>ce(a.id,"cancel")})},Ie=a=>{k({title:"Batalkan keputusan ini?",eyebrow:"lead · keputusan",message:"Keputusan ini ditandai dibatalkan dan tidak lagi berlaku.",confirmLabel:"Batalkan keputusan",icon:"x-circle",tone:"danger",run:()=>Le(a.id)})},Ae=a=>{if(j){if(a==="mati"){k({title:"Matikan lead?",eyebrow:"lead · kendali",message:"Lead berhenti memutuskan untuk semua project. Sesi yang sudah berjalan tidak diubah, dan pertanyaan yang menunggu tetap menunggu kamu.",confirmLabel:"Matikan lead",icon:"ban",tone:"danger",run:()=>$({...j,enabled:!1,paused:!1}).then(()=>{})});return}$({...j,enabled:!0,paused:a==="jeda"})}};if(J==="loading")return e.jsx(Re,{rows:4,label:"Memuat lead…"});if(J==="error"||!t)return e.jsx(_e,{kind:"error",hint:"Gagal memuat status lead.",action:()=>m(),actionLabel:"Coba lagi"});const oe=t.config.enabled?t.config.paused?"jeda":"aktif":"mati",ue=new Set(t.projects.map(a=>a.projectId)),W=t.waiting,he=new Set(t.deciding),se=new Set(t.queued??[]),V=t.gate??{inFlight:0,queued:0,capacity:1},De=a=>{const s=(t.queue??[]).find(x=>x.sessionId===a);if(s)return[U(s.projectId),s.specId].filter(Boolean).join(" · ");const r=P.find(x=>x.sessionId===a);return r?[U(r.projectId),r.specId].filter(Boolean).join(" · "):"Sesi (rincian ada di riwayat)"},me=[..._!=="rangkaian"?P.map(a=>({key:`d:${a.id}`,at:a.createdAt,d:a})):[],..._!=="keputusan"&&!f?C.map(a=>({key:`f:${a.id}`,at:a.openedAt,f:a})):[]].sort((a,s)=>Date.parse(s.at)-Date.parse(a.at)),Pe=_==="semua"?e.jsx(oa,{page:v,pageCount:Math.max(te(E,v,K).pageCount,te(d,v,K).pageCount),onPage:a=>{p(a),z(a)}}):_==="keputusan"?e.jsx(xe,{total:E,page:v,onPage:p,unit:"keputusan"}):e.jsx(xe,{total:d,page:I,onPage:z,unit:"rangkaian"}),Be=S==="all"?[]:[{key:"project",label:`Project: ${U(S)}`,onRemove:()=>ae("all")}];return e.jsxs("div",{className:"hn-lead",children:[e.jsxs("p",{className:"hn-lead-summary",children:["Lead ",ia[oe]," · ",W.length," menunggu kamu · ",se.size," antre"]}),e.jsxs("div",{className:"hn-lead-layout",children:[e.jsxs("div",{className:"hn-lead-main",children:[e.jsxs("section",{className:"hn-lead-section","aria-labelledby":"lead-menunggu-h",children:[e.jsxs("h2",{id:"lead-menunggu-h",className:"hn-lead-h",children:["Menunggu kamu (",W.length,")"]}),V.queued>0&&e.jsxs("p",{className:"hn-lead-note",children:["Antrean keputusan penuh: ",V.inFlight," dari ",V.capacity," sedang diputuskan, ",V.queued," menunggu giliran."]}),W.length===0?e.jsx("p",{className:"hn-lead-note",children:"Tidak ada sesi yang menunggu keputusanmu. Lead menangani sisanya."}):e.jsx("ul",{className:"hn-lead-waits",children:W.map(a=>{const s=he.has(a)?"Sedang diputuskan":se.has(a)?"Antre giliran":"Menunggu kamu",r=!he.has(a)&&!se.has(a);return e.jsx(ua,{sid:a,title:De(a),label:s,needsYou:r,onGoto:()=>u(a),onAnswered:()=>{i("Jawaban kamu dikirim ke sesi","ok","check"),m(!0)},onError:x=>i(x,"err","x-circle")},a)})})]}),e.jsxs("section",{className:"hn-lead-section","aria-labelledby":"lead-riwayat-h",children:[e.jsx("h2",{id:"lead-riwayat-h",className:"hn-lead-h",children:"Riwayat"}),e.jsx("div",{className:"hn-lead-chips",role:"group","aria-label":"Jenis riwayat",children:ta.map(a=>e.jsx("button",{type:"button",className:"hn-lead-chip","aria-pressed":_===a.key,onClick:()=>{a.key==="semua"&&z(v),ve(a.key)},children:a.label},a.key))}),e.jsx(Oe,{label:"Filter riwayat",chips:Be,filters:e.jsx(Ke,{gap:3,children:e.jsx(ke,{size:"sm",value:S,"aria-label":"saring project",onChange:a=>ae(a.target.value),options:[{value:"all",label:"semua project"},...n.map(a=>({value:a.id,label:a.name}))]})}),filtersLabel:"Project",onReset:()=>ae("all"),resetLabel:"Hapus filter",actions:e.jsxs(e.Fragment,{children:[e.jsx(qe,{screen:"lead",active:S==="all"?0:1}),e.jsx(aa,{})]})}),y&&e.jsx(je,{message:y,onRetry:()=>m()}),f&&_!=="keputusan"&&e.jsx(je,{message:"Gagal memuat rangkaian keputusan.",onRetry:()=>m()}),me.length===0?e.jsx("p",{className:"hn-lead-note",children:_==="rangkaian"?"Belum ada rangkaian. Satu rangkaian adalah satu urusan: beberapa pertanyaan berurutan sampai kamu kirim.":"Belum ada keputusan. Lead menulis satu baris di sini setiap kali ia memutuskan."}):e.jsx("ul",{className:"hn-lead-timeline","aria-label":"Riwayat keputusan dan rangkaian",children:me.map(a=>a.d?e.jsx(ma,{d:a.d,projectName:U,onOverride:Se,onCancel:Ie,busyId:T,ask:k},a.key):e.jsx(ga,{f:a.f,busyId:T,onClose:Ce},a.key))}),Pe]})]}),e.jsxs("aside",{className:"hn-lead-side","aria-label":"Kendali lead",children:[e.jsxs("section",{className:"hn-lead-section","aria-labelledby":"lead-kendali-h",children:[e.jsx("h2",{id:"lead-kendali-h",className:"hn-lead-h",children:"Kendali"}),e.jsx("div",{className:"hn-lead-mode",children:e.jsxs(fe,{label:"Mode lead",value:oe,onChange:a=>Ae(a),children:[e.jsx(Z,{value:"aktif",label:"Aktif",description:"Lead memutuskan untuk project yang diurusnya.",disabled:R}),e.jsx(Z,{value:"jeda",label:"Jeda",description:"Keputusan baru berhenti. Sesi yang berjalan tidak diubah.",disabled:R}),e.jsx(Z,{value:"mati",label:"Mati",description:"Lead berhenti total. Pertanyaan yang menunggu tetap menunggu kamu.",disabled:R})]})}),e.jsx($e,{tone:"info",title:"Dikunci secara teknis",children:"Produksi, VPS, dan penghapusan data tetap terkunci untuk lead, apa pun setelannya."})]}),e.jsxs("details",{className:"hn-lead-disclosure",children:[e.jsxs("summary",{children:["Project yang dipimpin · ",ue.size," dari ",n.length," diurus lead"]}),e.jsx("p",{className:"hn-lead-hint",children:"Lead hanya menyentuh project yang diserahkan kepadanya. Default: tidak diserahkan."}),n.length===0?e.jsx("p",{className:"hn-lead-note",children:"Belum ada project."}):e.jsx(Ge,{label:"Project yang dipimpin lead",children:n.map(a=>{const s=t.projects.find(x=>x.projectId===a.id),r=ue.has(a.id);return e.jsxs(Je,{actions:e.jsxs(e.Fragment,{children:[r&&(s!=null&&s.paused?e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"play",disabled:R,onClick:()=>de(a.id,!1),children:"Lanjutkan"}):e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"pause",disabled:R,onClick:()=>de(a.id,!0),children:"Jeda"})),r?e.jsx(g,{size:"sm",variant:"ghost",leftIcon:"ban",disabled:T===a.id,onClick:()=>re(a.id,!1),children:"Tarik dari lead"}):e.jsx(g,{size:"sm",leftIcon:"check",disabled:T===a.id,onClick:()=>re(a.id,!0),children:"Serahkan ke lead"})]}),children:[e.jsx("span",{className:"hn-lead-project-name",children:a.name}),s&&e.jsxs("span",{className:"hn-lead-project-meta",children:[s.decisions24h," keputusan 24 jam terakhir · ",s.openSessions," sesi terbuka"]}),e.jsx(G,{tone:r?s!=null&&s.paused?"warn":"ok":"neutral",size:"sm",children:r?s!=null&&s.paused?"dijeda":"diurus lead":"tidak diurus"})]},a.id)})})]}),e.jsxs("details",{className:"hn-lead-disclosure",children:[e.jsx("summary",{children:"Pengaturan lead"}),e.jsxs("div",{className:"hn-lead-settings",children:[e.jsxs("div",{className:"hn-lead-settings-grid",children:[e.jsx(Q,{label:"Lead memeriksa tiap (menit)",hint:"1–1440. Berlaku setelah Simpan.",children:e.jsx(Y,{type:"number",min:1,max:1440,"aria-label":"lead memeriksa tiap (menit)",placeholder:"mis. 5",value:c.draft.everyMin,disabled:!j,onChange:a=>c.setDraft({...c.draft,everyMin:a.target.value})})}),e.jsx(Q,{label:"Batas waktu keputusan (detik)",hint:"10–900. Lewat dari ini, keputusan gagal.",children:e.jsx(Y,{type:"number",min:10,max:900,"aria-label":"batas waktu keputusan (detik)",placeholder:"mis. 600",value:c.draft.timeoutSec,disabled:!j,onChange:a=>c.setDraft({...c.draft,timeoutSec:a.target.value})})}),e.jsx(Q,{label:"Jawaban otomatis per sesi (maks)",hint:"1–20. Setelah batas, sesi diserahkan ke kamu.",children:e.jsx(Y,{type:"number",min:1,max:20,"aria-label":"maksimum jawaban otomatis per sesi",placeholder:"mis. 3",value:c.draft.maxAutoAnswers,disabled:!j,onChange:a=>c.setDraft({...c.draft,maxAutoAnswers:a.target.value})})}),e.jsx(Q,{label:"Syarat integrasi ke main",hint:"Berlaku untuk integrasi yang diputuskan lead.",children:e.jsx(ke,{size:"sm","aria-label":"syarat integrasi ke main",value:c.draft.requireGreen?"wajib":"bebas",onChange:a=>c.setDraft({...c.draft,requireGreen:a.target.value==="wajib"}),options:[{value:"wajib",label:"plan harus tuntas dulu"},{value:"bebas",label:"tanpa syarat"}]})})]}),e.jsxs("div",{"data-testid":"lead-engine-line",className:"hn-lead-note",children:["Model lead: ",(ge=t.config.engine)!=null&&ge.enabled?e.jsxs(e.Fragment,{children:[t.config.engine.agent==="codex"?"Codex CLI":"Claude Code"," · ",e.jsx("code",{children:t.config.engine.model})," · ",e.jsx("code",{children:t.config.engine.effort})]}):e.jsx(e.Fragment,{children:"ikut default global · atur di Settings → Model sesi"})]}),e.jsxs("div",{className:"hn-lead-footer",children:[e.jsx("span",{role:"status","aria-live":"polite",children:ne?"Ada perubahan yang belum disimpan.":""}),e.jsxs("span",{className:"hn-lead-chips",children:[e.jsx(g,{size:"sm",variant:"ghost",disabled:!ne||R,onClick:()=>c.setDraft(q(t.config)),children:"Batal"}),e.jsx(g,{size:"sm",leftIcon:"check",disabled:!ne||R||!j,onClick:()=>void Ne(),children:"Simpan pengaturan"})]})]})]})]})]})]}),h]})}export{va as LeadScreen};
@@ -1 +1 @@
1
- import{d as Ne,aL as Te,aN as Ce,j as e,m as h,bj as De,B as d,U as Re,bk as Fe,aK as Me,aM as Pe,I as Ee,n as $e,aP as ze,C as Ke,O as Ae,h as b,bl as Le,i as T}from"./index-BvFCEJud.js";import{R as s}from"./react-DfGhg7ZW.js";import{D as Ue}from"./DocPreviewModal-Vysb114M.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";const He="(max-width: 399px)";function Ve(){const n=()=>typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(He):null,[C,j]=s.useState(()=>{var t;return((t=n())==null?void 0:t.matches)??!1});return s.useEffect(()=>{var u;const t=n();if(!t)return;const o=()=>j(t.matches);return o(),(u=t.addEventListener)==null||u.call(t,"change",o),()=>{var v;return(v=t.removeEventListener)==null?void 0:v.call(t,"change",o)}},[]),C}function Ze({specId:n,title:C,onBack:j,kind:t="spec",onGoto:o,onIntegrate:u,integrateTarget:v,onRevert:p,onDiscard:L,reviewed:w=!1,onMarkReviewed:x}){const le=t==="session"?b.sessionReview:b.specReview,ce=t==="session"?b.sessionReviewFile:b.specReviewFile,[k,U]=s.useState(null),[D,y]=s.useState("loading"),[oe,_e]=s.useState(""),[R,H]=s.useState(),[l,V]=s.useState(""),[r,F]=s.useState(null),[de,S]=s.useState("loading"),[ue,me]=s.useState(0),[_,he]=s.useState("diff"),[ke,M]=s.useState(0),[fe,ge]=s.useState("list"),[be,P]=s.useState(!1),[we,O]=s.useState("files"),{confirm:E,dialog:je}=Ne(),[W,m]=s.useState(""),$=Ve();s.useEffect(()=>{let a=!0;return y("loading"),le(n).then(i=>{var c;if(a){if(i.empty){U(null),H(i.reason),y("empty");return}U(i),H(void 0),y("ready"),V(((c=i.changed[0])==null?void 0:c.path)??i.files[0]??"")}}).catch(i=>{a&&(console.debug("review: gagal memuat",i==null?void 0:i.message),y("error"))}),()=>{a=!1}},[n,ke]),s.useEffect(()=>{if(!l){F(null),S("ready");return}let a=!0;return F(null),P(!1),S("loading"),ce(n,l).then(i=>{a&&(F(i),S("ready"))}).catch(()=>{a&&S("error")}),()=>{a=!1}},[n,l,ue]);const J=s.useMemo(()=>Te((k==null?void 0:k.files)??[]),[k]),f=(k==null?void 0:k.changed)??[],Q=f.reduce((a,i)=>a+i.add,0),Y=f.reduce((a,i)=>a+i.del,0),z=f.find(a=>a.path===l),X=!!r&&!r.binary&&r.content!==null&&Ce(l),Z=t==="session"?b.sessionReviewFileDownloadUrl:b.specReviewFileDownloadUrl,I=a=>{V(a),O("viewer")},q=t==="session"?"Kembali ke terminal":"Kembali ke backlog",K=!!(u||p||x),ve=`hanoman/${n.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,pe=K?u?"Integrasi menggabungkan branch item ke cabang tujuan. Konflik dibereskan sesi agen di Terminal.":"Tinjau perubahan, lalu putuskan.":t==="session"?"Merge dan konflik dikerjakan di Terminal.":"Merge dan konflik dikerjakan di Backlog. Buka Terminal untuk melanjutkan sesinya.",B={section:"terminal"},G={section:"ide"},A={section:"backlog",specId:n},N=a=>o==null?void 0:o(a),g=(a,i,c,re)=>o?e.jsx(d,{size:"sm",variant:re,leftIcon:c,onClick:()=>N(a),children:i}):e.jsx(d,{size:"sm",variant:re,leftIcon:c,as:"a",href:Le(a),children:i});async function ee(){const a=u;if(a){m("");try{await E({title:`Integrasikan ${n}?`,eyebrow:n,icon:"git-merge",confirmLabel:"Integrasikan",tone:"default",message:"Branch item di-merge ke cabang tujuan. Bila ada konflik, sesi agen membereskannya di Terminal. Rebase tetap di Backlog.",impact:[`Branch: ${ve}`,`${f.length} berkas berubah, +${Q} −${Y} baris`,`Cabang tujuan: ${v??"cabang asal item (default project)"}`],run:()=>a(n)})}catch(i){m(T("mengintegrasikan item",i))}}}async function ae(){const a=p;if(a){m("");try{const i=await a(n);if(!i||!("pending"in i))return;const c=i.wouldDelete;await E({title:`Kembalikan ${n} ke Dikerjakan?`,eyebrow:`${n} → Dikerjakan`,icon:"rotate-ccw",tone:c.length?"danger":"default",confirmLabel:c.length?"Hapus dokumen & kembalikan":"Kembalikan",message:c.length?`${c.length} berkas dokumen fase akan dihapus dari disk. Kode dan commit tidak disentuh.`:"Tak ada dokumen fase yang dihapus. Kode dan commit tidak disentuh.",impact:c,run:()=>a(n,!0)})}catch(i){m(T("mengembalikan status",i))}}}async function xe(){const a=L;if(a){m("");try{await E({title:`Hapus worktree ${n}?`,eyebrow:n,icon:"trash-2",tone:"danger",confirmLabel:"Hapus worktree",message:"Direktori worktree dipindah ke tempat sampah repo, lalu dibersihkan. Branch dan commit item tetap ada.",impact:["Sesi yang masih berjalan di worktree ini ditutup.","Perubahan yang belum di-commit di worktree ini ikut dibersihkan."],run:async()=>{await a(n),M(i=>i+1)}})}catch(i){m(T("menghapus worktree",i))}}}async function ie(){const a=x;if(a){m("");try{await a(n,!w)}catch(i){m(T("menandai ditinjau",i))}}}const ye={key:"backlog",label:"Buka di Backlog",icon:"list-checks",onSelect:()=>N(A)},Se={key:"terminal",label:"Buka di Terminal",icon:"terminal",onSelect:()=>N(B)},ne={key:"ide",label:"Buka di IDE",icon:"code",onSelect:()=>N(G)},te=t==="spec"?[ye]:[],Be=o?$?[...te,Se,ne]:K?[...te,ne]:[]:[],se=[...$?[...u?[{key:"integrate",label:"Integrasikan",icon:"git-merge",onSelect:()=>void ee()}]:[],...p?[{key:"revert",label:"Kembalikan ke Dikerjakan",icon:"rotate-ccw",onSelect:()=>void ae()}]:[],...x?[{key:"reviewed",label:w?"Batalkan tanda ditinjau":"Tandai ditinjau",icon:w?"rotate-ccw":"circle-check",onSelect:()=>void ie()}]:[]]:[],...Be,...L?[{key:"discard",label:"Hapus worktree",icon:"trash-2",tone:"danger",onSelect:()=>void xe()}]:[]];return D==="loading"?e.jsx(h,{kind:"loading",title:"Memuat review…",hint:n}):D==="error"?e.jsx(h,{kind:"error",title:"Gagal memuat review",hint:n,action:()=>M(a=>a+1)}):D==="empty"?e.jsxs("div",{className:"hn-review-empty","data-review-state":"empty","data-reason":R??"409","data-status":R?"200":"409","data-detail":oe||void 0,children:[e.jsx(h,{kind:"empty",icon:"git-branch",title:"Belum ada perubahan untuk ditinjau",hint:R==="no-commit"?"Worktree sudah dilepas dan belum ada commit untuk ditinjau. Jalankan sesinya lagi bila perlu.":"Sesi belum membuat worktree. Jalankan atau lanjutkan sesinya dulu, lalu muat ulang."}),e.jsxs(De,{gap:2,justify:"center",children:[t==="spec"&&g(A,"Buka di Backlog","list-checks","primary"),g(B,"Buka di Terminal","terminal",t==="session"?"primary":"secondary"),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:j,children:q})]})]}):e.jsxs("div",{className:"hn-review",children:[e.jsxs("header",{className:"hn-review-topbar",children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:j,children:q}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"rotate-ccw",onClick:()=>M(a=>a+1),children:"Muat ulang"})]}),e.jsxs("div",{className:"hn-review-head",children:[e.jsx("span",{className:"hn-eyebrow",children:n}),e.jsx("h2",{className:"hn-review-title",children:C||n}),e.jsxs("p",{className:"hn-review-stat",children:[f.length," berkas berubah · ",e.jsx("span",{className:"hn-review-delta",children:`+${Q} −${Y}`})," baris"]})]}),e.jsx(Re,{ariaLabel:"Panel Review",active:we,onActiveChange:a=>O(a),masterWidth:300,panels:[{id:"files",label:"Files",content:e.jsxs("section",{className:"hn-review-pane","aria-label":"Daftar berkas",children:[e.jsxs("div",{className:"hn-review-list",children:[e.jsx(Fe,{label:"Changed",changed:f,selected:l,onSelect:I,view:fe,onView:ge}),e.jsx("div",{className:"hn-eyebrow hn-review-sep",children:"Semua berkas"}),e.jsx(Me,{label:"Pohon berkas",nodes:J,children:J.map(a=>e.jsx(Pe,{node:a,selected:l,onSelect:I},a.path))})]}),e.jsx("p",{className:"hn-review-legend",children:"A = baru · M = diubah · D = dihapus"})]})},{id:"viewer",label:"Viewer",content:e.jsxs("section",{className:"hn-review-viewer","aria-label":"Isi berkas",children:[e.jsxs("div",{className:"hn-review-viewbar",children:[e.jsx(Ee,{name:"file-text",size:15,color:"var(--text-muted)"}),e.jsx("span",{className:"hn-review-path",children:l||"—"}),(r==null?void 0:r.status)&&e.jsx($e,{tone:r.status==="D"?"err":r.status==="A"?"ok":"brass",size:"sm",children:r.status}),z&&e.jsxs("span",{className:"hn-review-filestat",children:["+",z.add," −",z.del]}),X&&e.jsx(d,{size:"sm",variant:"secondary",leftIcon:"book-open",onClick:()=>P(!0),children:"Preview"}),e.jsx("div",{className:"hn-review-seg",children:["diff","source"].map(a=>e.jsx("button",{type:"button","aria-pressed":_===a,onClick:()=>he(a),children:a==="diff"?"Diff":"Sumber"},a))})]}),e.jsx("div",{className:"hn-review-body",children:l?de==="error"?e.jsx(h,{kind:"error",title:"Gagal memuat berkas",hint:l,action:()=>me(a=>a+1)}):r?r.binary?e.jsx(h,{kind:"empty",icon:"file",title:"Berkas biner",hint:"Tak dapat di-review dari dashboard."}):_==="diff"?e.jsxs("div",{className:"hn-review-diff",children:[e.jsx(ze,{diff:r.diff??"",emptyHint:"File ini bagian dari project, tetapi tidak diubah oleh item ini."}),r.truncated&&e.jsxs("div",{className:"hn-review-truncated",children:[e.jsx("span",{children:"… dipotong pada 256 KB."}),e.jsx("a",{href:Z(n,l,"md"),download:!0,children:"Unduh berkas utuh"})]})]}):r.content===null?e.jsx(h,{kind:"empty",icon:"trash-2",title:"File dihapus",hint:"Tak ada isi untuk ditampilkan."}):e.jsx("pre",{className:"hn-review-pre",children:r.content}):e.jsx(h,{kind:"loading",title:"Memuat file…",hint:l}):e.jsx(h,{kind:"empty",icon:"file-text",title:"Pilih file",hint:"Pilih file dari changed atau tree."})})]})}]}),e.jsxs("div",{className:"hn-review-decide",role:"region","aria-label":"Keputusan",children:[W&&e.jsx(Ke,{tone:"err",className:"hn-review-decide-err",children:W}),e.jsx("p",{className:"hn-review-decide-hint",children:pe}),e.jsxs("div",{className:"hn-review-decide-actions",children:[!$&&(K?e.jsxs(e.Fragment,{children:[p&&e.jsx(d,{size:"sm",variant:"secondary",leftIcon:"rotate-ccw",onClick:()=>void ae(),children:"Kembalikan ke Dikerjakan"}),x&&e.jsx(d,{size:"sm",variant:"secondary",leftIcon:w?"rotate-ccw":"circle-check",onClick:()=>void ie(),children:w?"Batalkan tanda ditinjau":"Tandai ditinjau"}),u&&e.jsx(d,{size:"sm",variant:"primary",leftIcon:"git-merge",onClick:()=>void ee(),children:"Integrasikan"}),g(B,"Buka di Terminal","terminal","secondary")]}):e.jsxs(e.Fragment,{children:[t==="spec"&&g(A,"Buka di Backlog","list-checks","primary"),g(B,"Buka di Terminal","terminal",t==="session"?"primary":"secondary"),g(G,"Buka di IDE","code","secondary")]})),se.length>0&&e.jsx("div",{className:"hn-review-more",children:e.jsx(Ae,{label:"Aksi lain",items:se})})]})]}),je,be&&X&&e.jsx(Ue,{path:l,text:r.content??"",eyebrow:n,download:a=>Z(n,l,a),onClose:()=>P(!1)})]})}export{Ze as ReviewScreen};
1
+ import{d as Ne,aL as Te,aN as Ce,j as e,m as h,bj as De,B as d,U as Re,bk as Fe,aK as Me,aM as Pe,I as Ee,n as $e,aP as ze,C as Ke,O as Ae,h as b,bl as Le,i as T}from"./index-Av-RfHXX.js";import{R as s}from"./react-DfGhg7ZW.js";import{D as Ue}from"./DocPreviewModal-ClHbRVmQ.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";const He="(max-width: 399px)";function Ve(){const n=()=>typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(He):null,[C,j]=s.useState(()=>{var t;return((t=n())==null?void 0:t.matches)??!1});return s.useEffect(()=>{var u;const t=n();if(!t)return;const o=()=>j(t.matches);return o(),(u=t.addEventListener)==null||u.call(t,"change",o),()=>{var v;return(v=t.removeEventListener)==null?void 0:v.call(t,"change",o)}},[]),C}function Ze({specId:n,title:C,onBack:j,kind:t="spec",onGoto:o,onIntegrate:u,integrateTarget:v,onRevert:p,onDiscard:L,reviewed:w=!1,onMarkReviewed:x}){const le=t==="session"?b.sessionReview:b.specReview,ce=t==="session"?b.sessionReviewFile:b.specReviewFile,[k,U]=s.useState(null),[D,y]=s.useState("loading"),[oe,_e]=s.useState(""),[R,H]=s.useState(),[l,V]=s.useState(""),[r,F]=s.useState(null),[de,S]=s.useState("loading"),[ue,me]=s.useState(0),[_,he]=s.useState("diff"),[ke,M]=s.useState(0),[fe,ge]=s.useState("list"),[be,P]=s.useState(!1),[we,O]=s.useState("files"),{confirm:E,dialog:je}=Ne(),[W,m]=s.useState(""),$=Ve();s.useEffect(()=>{let a=!0;return y("loading"),le(n).then(i=>{var c;if(a){if(i.empty){U(null),H(i.reason),y("empty");return}U(i),H(void 0),y("ready"),V(((c=i.changed[0])==null?void 0:c.path)??i.files[0]??"")}}).catch(i=>{a&&(console.debug("review: gagal memuat",i==null?void 0:i.message),y("error"))}),()=>{a=!1}},[n,ke]),s.useEffect(()=>{if(!l){F(null),S("ready");return}let a=!0;return F(null),P(!1),S("loading"),ce(n,l).then(i=>{a&&(F(i),S("ready"))}).catch(()=>{a&&S("error")}),()=>{a=!1}},[n,l,ue]);const J=s.useMemo(()=>Te((k==null?void 0:k.files)??[]),[k]),f=(k==null?void 0:k.changed)??[],Q=f.reduce((a,i)=>a+i.add,0),Y=f.reduce((a,i)=>a+i.del,0),z=f.find(a=>a.path===l),X=!!r&&!r.binary&&r.content!==null&&Ce(l),Z=t==="session"?b.sessionReviewFileDownloadUrl:b.specReviewFileDownloadUrl,I=a=>{V(a),O("viewer")},q=t==="session"?"Kembali ke terminal":"Kembali ke backlog",K=!!(u||p||x),ve=`hanoman/${n.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,pe=K?u?"Integrasi menggabungkan branch item ke cabang tujuan. Konflik dibereskan sesi agen di Terminal.":"Tinjau perubahan, lalu putuskan.":t==="session"?"Merge dan konflik dikerjakan di Terminal.":"Merge dan konflik dikerjakan di Backlog. Buka Terminal untuk melanjutkan sesinya.",B={section:"terminal"},G={section:"ide"},A={section:"backlog",specId:n},N=a=>o==null?void 0:o(a),g=(a,i,c,re)=>o?e.jsx(d,{size:"sm",variant:re,leftIcon:c,onClick:()=>N(a),children:i}):e.jsx(d,{size:"sm",variant:re,leftIcon:c,as:"a",href:Le(a),children:i});async function ee(){const a=u;if(a){m("");try{await E({title:`Integrasikan ${n}?`,eyebrow:n,icon:"git-merge",confirmLabel:"Integrasikan",tone:"default",message:"Branch item di-merge ke cabang tujuan. Bila ada konflik, sesi agen membereskannya di Terminal. Rebase tetap di Backlog.",impact:[`Branch: ${ve}`,`${f.length} berkas berubah, +${Q} −${Y} baris`,`Cabang tujuan: ${v??"cabang asal item (default project)"}`],run:()=>a(n)})}catch(i){m(T("mengintegrasikan item",i))}}}async function ae(){const a=p;if(a){m("");try{const i=await a(n);if(!i||!("pending"in i))return;const c=i.wouldDelete;await E({title:`Kembalikan ${n} ke Dikerjakan?`,eyebrow:`${n} → Dikerjakan`,icon:"rotate-ccw",tone:c.length?"danger":"default",confirmLabel:c.length?"Hapus dokumen & kembalikan":"Kembalikan",message:c.length?`${c.length} berkas dokumen fase akan dihapus dari disk. Kode dan commit tidak disentuh.`:"Tak ada dokumen fase yang dihapus. Kode dan commit tidak disentuh.",impact:c,run:()=>a(n,!0)})}catch(i){m(T("mengembalikan status",i))}}}async function xe(){const a=L;if(a){m("");try{await E({title:`Hapus worktree ${n}?`,eyebrow:n,icon:"trash-2",tone:"danger",confirmLabel:"Hapus worktree",message:"Direktori worktree dipindah ke tempat sampah repo, lalu dibersihkan. Branch dan commit item tetap ada.",impact:["Sesi yang masih berjalan di worktree ini ditutup.","Perubahan yang belum di-commit di worktree ini ikut dibersihkan."],run:async()=>{await a(n),M(i=>i+1)}})}catch(i){m(T("menghapus worktree",i))}}}async function ie(){const a=x;if(a){m("");try{await a(n,!w)}catch(i){m(T("menandai ditinjau",i))}}}const ye={key:"backlog",label:"Buka di Backlog",icon:"list-checks",onSelect:()=>N(A)},Se={key:"terminal",label:"Buka di Terminal",icon:"terminal",onSelect:()=>N(B)},ne={key:"ide",label:"Buka di IDE",icon:"code",onSelect:()=>N(G)},te=t==="spec"?[ye]:[],Be=o?$?[...te,Se,ne]:K?[...te,ne]:[]:[],se=[...$?[...u?[{key:"integrate",label:"Integrasikan",icon:"git-merge",onSelect:()=>void ee()}]:[],...p?[{key:"revert",label:"Kembalikan ke Dikerjakan",icon:"rotate-ccw",onSelect:()=>void ae()}]:[],...x?[{key:"reviewed",label:w?"Batalkan tanda ditinjau":"Tandai ditinjau",icon:w?"rotate-ccw":"circle-check",onSelect:()=>void ie()}]:[]]:[],...Be,...L?[{key:"discard",label:"Hapus worktree",icon:"trash-2",tone:"danger",onSelect:()=>void xe()}]:[]];return D==="loading"?e.jsx(h,{kind:"loading",title:"Memuat review…",hint:n}):D==="error"?e.jsx(h,{kind:"error",title:"Gagal memuat review",hint:n,action:()=>M(a=>a+1)}):D==="empty"?e.jsxs("div",{className:"hn-review-empty","data-review-state":"empty","data-reason":R??"409","data-status":R?"200":"409","data-detail":oe||void 0,children:[e.jsx(h,{kind:"empty",icon:"git-branch",title:"Belum ada perubahan untuk ditinjau",hint:R==="no-commit"?"Worktree sudah dilepas dan belum ada commit untuk ditinjau. Jalankan sesinya lagi bila perlu.":"Sesi belum membuat worktree. Jalankan atau lanjutkan sesinya dulu, lalu muat ulang."}),e.jsxs(De,{gap:2,justify:"center",children:[t==="spec"&&g(A,"Buka di Backlog","list-checks","primary"),g(B,"Buka di Terminal","terminal",t==="session"?"primary":"secondary"),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:j,children:q})]})]}):e.jsxs("div",{className:"hn-review",children:[e.jsxs("header",{className:"hn-review-topbar",children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:j,children:q}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"rotate-ccw",onClick:()=>M(a=>a+1),children:"Muat ulang"})]}),e.jsxs("div",{className:"hn-review-head",children:[e.jsx("span",{className:"hn-eyebrow",children:n}),e.jsx("h2",{className:"hn-review-title",children:C||n}),e.jsxs("p",{className:"hn-review-stat",children:[f.length," berkas berubah · ",e.jsx("span",{className:"hn-review-delta",children:`+${Q} −${Y}`})," baris"]})]}),e.jsx(Re,{ariaLabel:"Panel Review",active:we,onActiveChange:a=>O(a),masterWidth:300,panels:[{id:"files",label:"Files",content:e.jsxs("section",{className:"hn-review-pane","aria-label":"Daftar berkas",children:[e.jsxs("div",{className:"hn-review-list",children:[e.jsx(Fe,{label:"Changed",changed:f,selected:l,onSelect:I,view:fe,onView:ge}),e.jsx("div",{className:"hn-eyebrow hn-review-sep",children:"Semua berkas"}),e.jsx(Me,{label:"Pohon berkas",nodes:J,children:J.map(a=>e.jsx(Pe,{node:a,selected:l,onSelect:I},a.path))})]}),e.jsx("p",{className:"hn-review-legend",children:"A = baru · M = diubah · D = dihapus"})]})},{id:"viewer",label:"Viewer",content:e.jsxs("section",{className:"hn-review-viewer","aria-label":"Isi berkas",children:[e.jsxs("div",{className:"hn-review-viewbar",children:[e.jsx(Ee,{name:"file-text",size:15,color:"var(--text-muted)"}),e.jsx("span",{className:"hn-review-path",children:l||"—"}),(r==null?void 0:r.status)&&e.jsx($e,{tone:r.status==="D"?"err":r.status==="A"?"ok":"brass",size:"sm",children:r.status}),z&&e.jsxs("span",{className:"hn-review-filestat",children:["+",z.add," −",z.del]}),X&&e.jsx(d,{size:"sm",variant:"secondary",leftIcon:"book-open",onClick:()=>P(!0),children:"Preview"}),e.jsx("div",{className:"hn-review-seg",children:["diff","source"].map(a=>e.jsx("button",{type:"button","aria-pressed":_===a,onClick:()=>he(a),children:a==="diff"?"Diff":"Sumber"},a))})]}),e.jsx("div",{className:"hn-review-body",children:l?de==="error"?e.jsx(h,{kind:"error",title:"Gagal memuat berkas",hint:l,action:()=>me(a=>a+1)}):r?r.binary?e.jsx(h,{kind:"empty",icon:"file",title:"Berkas biner",hint:"Tak dapat di-review dari dashboard."}):_==="diff"?e.jsxs("div",{className:"hn-review-diff",children:[e.jsx(ze,{diff:r.diff??"",emptyHint:"File ini bagian dari project, tetapi tidak diubah oleh item ini."}),r.truncated&&e.jsxs("div",{className:"hn-review-truncated",children:[e.jsx("span",{children:"… dipotong pada 256 KB."}),e.jsx("a",{href:Z(n,l,"md"),download:!0,children:"Unduh berkas utuh"})]})]}):r.content===null?e.jsx(h,{kind:"empty",icon:"trash-2",title:"File dihapus",hint:"Tak ada isi untuk ditampilkan."}):e.jsx("pre",{className:"hn-review-pre",children:r.content}):e.jsx(h,{kind:"loading",title:"Memuat file…",hint:l}):e.jsx(h,{kind:"empty",icon:"file-text",title:"Pilih file",hint:"Pilih file dari changed atau tree."})})]})}]}),e.jsxs("div",{className:"hn-review-decide",role:"region","aria-label":"Keputusan",children:[W&&e.jsx(Ke,{tone:"err",className:"hn-review-decide-err",children:W}),e.jsx("p",{className:"hn-review-decide-hint",children:pe}),e.jsxs("div",{className:"hn-review-decide-actions",children:[!$&&(K?e.jsxs(e.Fragment,{children:[p&&e.jsx(d,{size:"sm",variant:"secondary",leftIcon:"rotate-ccw",onClick:()=>void ae(),children:"Kembalikan ke Dikerjakan"}),x&&e.jsx(d,{size:"sm",variant:"secondary",leftIcon:w?"rotate-ccw":"circle-check",onClick:()=>void ie(),children:w?"Batalkan tanda ditinjau":"Tandai ditinjau"}),u&&e.jsx(d,{size:"sm",variant:"primary",leftIcon:"git-merge",onClick:()=>void ee(),children:"Integrasikan"}),g(B,"Buka di Terminal","terminal","secondary")]}):e.jsxs(e.Fragment,{children:[t==="spec"&&g(A,"Buka di Backlog","list-checks","primary"),g(B,"Buka di Terminal","terminal",t==="session"?"primary":"secondary"),g(G,"Buka di IDE","code","secondary")]})),se.length>0&&e.jsx("div",{className:"hn-review-more",children:e.jsx(Ae,{label:"Aksi lain",items:se})})]})]}),je,be&&X&&e.jsx(Ue,{path:l,text:r.content??"",eyebrow:n,download:a=>Z(n,l,a),onClose:()=>P(!1)})]})}export{Ze as ReviewScreen};
@@ -1 +1 @@
1
- import{d as pe,q as T,D as Re,W as Be,h as I,i as L,aZ as Me,a_ as ze,j as e,g as O,B as C,I as Oe,L as G,aJ as $e,n as Q,a$ as He,O as De,M as Fe,c as be,aW as $,e as P,f as M,b0 as Te,H as Ue,b1 as te,b2 as ce,a9 as _e,b3 as Je,b4 as W,V as je,R as Z,X as D,l as _,b5 as Ge,a2 as xe,Z as ke,r as ge,G as ve,m as Qe,Y as Ke,b6 as Ye,b7 as We,b8 as Ze,P as Ve,b9 as J,F as Xe,ba as fe,_ as qe}from"./index-BvFCEJud.js";import{R as o}from"./react-DfGhg7ZW.js";import{L as ea}from"./live-B2RFSX3l.js";import"./markdown-CWEY34jk.js";import{b as aa,I as V,c as H,f as na,u as sa,a as ye,d as ta}from"./sched-lead-shared-0mpQqjza.js";/* empty css */import{r as ra,O as la}from"./settings-rebase-BVFljdPX.js";import"./xterm-3VOAfa_q.js";const de=10,ee=a=>{var s;return(s=a.detail)==null?void 0:s.error},ae=a=>String(a).padStart(2,"0"),oe=a=>{const s={name:(a==null?void 0:a.name)??"",prompt:(a==null?void 0:a.prompt)??"",enabled:(a==null?void 0:a.enabled)??!1,kind:"lanjutan",time:"07:00",weekday:1,everyHours:"6",expr:(a==null?void 0:a.expr)??"0 7 * * *",agent:(a==null?void 0:a.agent)??"",model:(a==null?void 0:a.model)??"",effort:(a==null?void 0:a.effort)??""},t=a?Je(a.expr):{kind:"harian",hour:7,minute:0};if(!t)return s;if(t.kind==="tiap-n-jam")return{...s,kind:t.kind,everyHours:String(t.everyHours),time:`00:${ae(t.minute)}`};const r=`${ae(t.hour)}:${ae(t.minute)}`;return t.kind==="mingguan"?{...s,kind:t.kind,time:r,weekday:t.weekday}:{...s,kind:t.kind,time:r}},ia=a=>{if(a.kind==="lanjutan")return a.expr.trim();const[s,t]=a.time.split(":").map(Number);switch(a.kind){case"harian":return W({kind:"harian",hour:s,minute:t});case"hari-kerja":return W({kind:"hari-kerja",hour:s,minute:t});case"mingguan":return W({kind:"mingguan",hour:s,minute:t,weekday:a.weekday});case"tiap-n-jam":return W({kind:"tiap-n-jam",everyHours:H(a.everyHours,1,23,6),minute:t})}},ca={launched:"ok",queued:"neutral",skipped:"warn",failed:"err"};function da({cronId:a,at:s}){const[t,r]=o.useState([]),[k,m]=o.useState(0),[b,d]=o.useState(!1),[g,j]=o.useState(null),[v,w]=T("scheduler","cronRunsPage",1,je),u=o.useCallback(()=>{let c=!0;return I.listCronRuns(a,{page:v,limit:de}).then(x=>{c&&(r(x.items),m(x.total),d(!0),j(null))}).catch(x=>{c&&(j(L("memuat riwayat",x)),d(!0))}),()=>{c=!1}},[a,v]);if(o.useEffect(()=>u(),[u]),g)return e.jsx(V,{message:g,onRetry:()=>{u()}});if(!b)return e.jsx(G,{rows:2,label:"Memuat riwayat…"});if(k===0)return e.jsx("p",{className:"hn-sched-empty",children:"Belum ada eksekusi."});const l=ke(k,v,de);return e.jsxs(e.Fragment,{children:[e.jsx(Z,{label:"Riwayat eksekusi",children:t.map(c=>e.jsx(D,{children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx("span",{className:"hn-sched-row-head",children:e.jsx(Q,{tone:ca[c.status]??"neutral",size:"sm",children:_(Ge,c.status)})}),e.jsxs("span",{className:"hn-sched-row-meta",children:["jatuh tempo ",s(c.dueAt),c.startedAt?` · mulai ${s(c.startedAt)}`:"",c.manual?" · uji coba":"",c.note?` · ${c.note}`:""]})]})},c.id))}),e.jsx(xe,{page:l.page,pageCount:l.pageCount,total:k,from:l.from,to:l.to,onPage:w,unit:"run"})]})}function oa({projects:a,onProjectChanged:s,onToast:t,timeZone:r}){var ie;const{confirm:k,dialog:m}=pe(),b=r??aa(),d=n=>na(n,b),[g,j]=T("scheduler","cronProject",((ie=a[0])==null?void 0:ie.id)??"",Re),[v,w]=o.useState([]),[u,l]=o.useState(!1),[c,x]=o.useState(null),[E,N]=o.useState(void 0),[i,S]=o.useState(oe()),[X,Y]=o.useState("dasar"),[F,re]=T("scheduler","cronOpenRuns",null,Be),[R,A]=o.useState(!1),z=a.find(n=>n.id===g),B=o.useCallback(()=>{if(!g){w([]),x(null),l(!0);return}I.listCrons({projectId:g,page:1,limit:100}).then(n=>{w(n.items),x(null),l(!0)}).catch(n=>{x(L("memuat daftar cron",n)),l(!0)})},[g]);o.useEffect(()=>{w([]),l(!1),B()},[B]);const h=n=>{N(n??null),S(oe(n)),Y("dasar")},f=ia(i),y=Me(f)!==null,U=y?ze(f,new Date,b):null,Ce=async()=>{if(!y){t("Ekspresi cron tidak sah","err","x-circle");return}A(!0);try{E?await I.patchCron(E.id,{name:i.name,expr:f,prompt:i.prompt,enabled:i.enabled,agent:i.agent||null,model:i.model||null,effort:i.effort||null}):await I.createCron({project:g,name:i.name,expr:f,prompt:i.prompt,enabled:i.enabled,agent:i.agent||void 0,model:i.model||void 0,effort:i.effort||void 0}),t("Cron tersimpan","ok","save"),N(void 0),B()}catch(n){t(ee(n)??L("menyimpan cron",n),"err","x-circle")}finally{A(!1)}},Ne=async n=>{A(!0);try{await I.runCronNow(n),t("Uji coba masuk antrean; sesi dibuka pada siklus berikutnya","ok","play")}catch(p){t(ee(p)??L("menjalankan cron",p),"err","x-circle")}finally{A(!1),B()}},Ie=async n=>{A(!0);try{await I.deleteCron(n),t("Cron dihapus","ok","trash")}catch(p){t(ee(p)??L("menghapus cron",p),"err","x-circle")}finally{A(!1),B()}},Pe=n=>{k({title:"Hapus cron ini?",eyebrow:"scheduler · cronjob",impact:[`Cron "${n.name}" di project ${(z==null?void 0:z.name)??"ini"} dihapus permanen.`,"Jadwalnya berhenti dan tidak akan dijalankan lagi.","Tindakan ini tidak bisa dibatalkan."],confirmLabel:"Hapus cron",icon:"trash-2",tone:"danger",run:()=>Ie(n.id)})},Ae=async()=>{if(g)try{await I.updateProject(g,{schedulerOptIn:!0}),await s(g),t("Project diizinkan untuk scheduler","ok")}catch(n){t(L("mengizinkan project",n),"err","x-circle")}},Le=n=>[{key:"edit",label:"Ubah",icon:"pencil",onSelect:()=>h(n)},{key:"run",label:"Jalankan sekarang",icon:"play",disabled:R,onSelect:()=>void Ne(n.id)},{key:"runs",label:F===n.id?"Sembunyikan riwayat":"Riwayat",icon:"list",onSelect:()=>re(F===n.id?null:n.id)},{key:"remove",label:"Hapus",icon:"trash",tone:"danger",disabled:R,onSelect:()=>Pe(n)}],q=i.agent||"claude",le=()=>S(n=>({...n,everyHours:String(H(n.everyHours,1,23,6))})),Ee=y?U?`Perkiraan jalan berikutnya: ${d(U.toISOString())}`:`Preview belum bisa dihitung untuk zona ${b}. Jam jalan berikutnya tampil di daftar cron.`:"Jadwal tidak sah, jadi tidak ada jalan berikutnya.";return e.jsxs("div",{className:"hn-sched-panel",children:[e.jsxs("div",{className:"hn-sched-toolbar",children:[e.jsx(O,{value:g,"aria-label":"Project",onChange:n=>j(n.target.value),options:a.map(n=>({value:n.id,label:n.name}))}),e.jsx(C,{size:"sm",leftIcon:"plus",disabled:!g,onClick:()=>h(),children:"Cron baru"})]}),e.jsxs("p",{className:"hn-sched-caption",children:["Jam ditampilkan dalam zona server ",e.jsx("b",{children:b}),r===void 0?" (server belum melaporkan zonanya, jadi zona browser yang dipakai)":"","."]}),z&&!z.schedulerOptIn&&e.jsx("div",{className:"hn-sched-notice",children:e.jsxs("div",{className:"hn-dense-row",role:"note",children:[e.jsx(Oe,{name:"alert-triangle",size:16,color:"var(--clay-600)"}),e.jsx("span",{className:"hn-grow hn-sched-notice-text",children:"Project ini belum diizinkan untuk scheduler, jadi cron-nya tidak akan pernah dijalankan."}),e.jsx(C,{size:"sm",leftIcon:"check",onClick:()=>void Ae(),children:"Aktifkan scheduler di project ini"})]})}),c?e.jsx(V,{message:c,onRetry:B,busy:R}):u?v.length===0?e.jsx("p",{className:"hn-sched-empty",children:"Belum ada cron di project ini."}):e.jsx($e,{children:e.jsxs("table",{className:"hn-sched-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",children:"Cron"}),e.jsx("th",{scope:"col",children:"Jadwal"}),e.jsx("th",{scope:"col",children:"Terakhir"}),e.jsx("th",{scope:"col",children:"Berikutnya"}),e.jsx("th",{scope:"col",children:e.jsx("span",{className:"hn-sr-only",children:"Aksi"})})]})}),e.jsx("tbody",{children:v.map(n=>e.jsxs(o.Fragment,{children:[e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Cron",children:e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx("span",{className:"hn-sched-row-title",children:n.name}),e.jsx(Q,{tone:n.enabled?"ok":"neutral",size:"sm",children:n.enabled?"aktif":"nonaktif"})]})}),e.jsx("td",{"data-label":"Jadwal",children:He(n.expr)}),e.jsx("td",{"data-label":"Terakhir",children:d(n.lastRunAt)}),e.jsx("td",{"data-label":"Berikutnya",children:d(n.nextRunAt)}),e.jsx("td",{className:"hn-sched-cell-actions",children:e.jsx(De,{label:`Aksi untuk cron ${n.name}`,title:n.name,items:Le(n)})})]}),F===n.id&&e.jsx("tr",{className:"hn-sched-runs",children:e.jsx("td",{colSpan:5,children:e.jsx("div",{id:`cron-runs-${n.id}`,children:e.jsx(da,{cronId:n.id,at:d})})})})]},n.id))})]})}):e.jsx(G,{rows:3,label:"Memuat daftar cron…"}),e.jsx(Fe,{open:E!==void 0,title:E?"Ubah cron":"Cron baru",eyebrow:"scheduler",onClose:()=>N(void 0),width:640,footer:e.jsxs("div",{className:"hn-sched-savebar",children:[e.jsx(C,{size:"sm",variant:"ghost",onClick:()=>N(void 0),children:"Batal"}),e.jsx(C,{size:"sm",leftIcon:"save",disabled:R,onClick:()=>void Ce(),children:"Simpan"})]}),children:e.jsxs(be,{tabs:[{value:"dasar",label:"Dasar"},{value:"lanjutan",label:"Lanjutan"}],value:X,onChange:n=>Y(n),children:[e.jsxs($,{value:"dasar",className:"hn-sched-panel",children:[e.jsx(P,{label:"Nama cron",children:e.jsx(M,{"aria-label":"Nama cron",placeholder:"mis. Cek error produksi pagi",value:i.name,onChange:n=>S(p=>({...p,name:n.target.value}))})}),e.jsxs("div",{className:"hn-sched-form-grid",children:[e.jsx(P,{label:"Preset jadwal",children:e.jsx(O,{"aria-label":"Preset jadwal",value:i.kind,onChange:n=>S(p=>({...p,kind:n.target.value})),options:[{value:"harian",label:"Setiap hari"},{value:"hari-kerja",label:"Hari kerja"},{value:"mingguan",label:"Mingguan"},{value:"tiap-n-jam",label:"Tiap N jam"},{value:"lanjutan",label:"Ekspresi cron (lanjutan)"}]})}),i.kind!=="lanjutan"&&e.jsx(P,{label:i.kind==="tiap-n-jam"?"Menit pada setiap jam":"Jam",children:e.jsx(M,{type:"time","aria-label":"Jam",value:i.time,onChange:n=>S(p=>({...p,time:n.target.value}))})}),i.kind==="mingguan"&&e.jsx(P,{label:"Hari",children:e.jsx(O,{"aria-label":"Hari",value:String(i.weekday),onChange:n=>S(p=>({...p,weekday:Number(n.target.value)})),options:Te.map((n,p)=>({value:String(p),label:n}))})}),i.kind==="tiap-n-jam"&&e.jsx(P,{label:"Tiap berapa jam",children:e.jsx(M,{type:"number",min:1,max:23,"aria-label":"Tiap berapa jam",placeholder:"mis. 6",value:i.everyHours,onChange:n=>S(p=>({...p,everyHours:n.target.value})),onBlur:le,onKeyDown:n=>{n.key==="Enter"&&(n.preventDefault(),le())}})})]}),i.kind==="lanjutan"&&e.jsx(P,{label:"Ekspresi cron",hint:"Lima bagian: menit, jam, tanggal, bulan, hari dalam minggu.",children:e.jsx(M,{"aria-label":"Ekspresi cron",placeholder:"mis. 0 7 * * 1-5",value:i.expr,onChange:n=>S(p=>({...p,expr:n.target.value}))})}),e.jsx("p",{"data-testid":"cron-next-preview",className:`hn-sched-note${U?"":" hn-sched-preview-warn"}`,children:Ee}),e.jsxs("p",{className:"hn-sched-note",children:["Jadwal berlaku menurut zona waktu server ",e.jsx("b",{children:b}),"."]}),e.jsx(P,{label:"Prompt",hint:"Instruksi bebas untuk agen. Temuan sebaiknya dicatat sebagai item backlog baru.",children:e.jsx(Ue,{"aria-label":"Prompt",rows:6,placeholder:"mis. Periksa error 5xx sejak kemarin, lalu catat temuannya sebagai QA finding.",value:i.prompt,onChange:n=>S(p=>({...p,prompt:n.target.value}))})}),e.jsx(te,{label:"Aktif",checked:i.enabled,onChange:n=>S(p=>({...p,enabled:n}))})]}),e.jsxs($,{value:"lanjutan",className:"hn-sched-panel",children:[e.jsx("p",{className:"hn-sched-group-hint",children:"Kosongkan untuk mengikuti default sesi. Model dan effort baru tersedia setelah runtime dipilih."}),e.jsxs("div",{className:"hn-sched-form-grid",children:[e.jsx(P,{label:"Runtime",children:e.jsx(O,{"aria-label":"Runtime",value:i.agent,onChange:n=>S(p=>({...p,agent:n.target.value,model:"",effort:""})),options:[{value:"",label:"Ikuti default sesi"},{value:"claude",label:"Claude Code"},{value:"codex",label:"Codex CLI"}]})}),e.jsx(P,{label:"Model",children:e.jsx(O,{"aria-label":"Model",value:i.model,disabled:!i.agent,onChange:n=>S(p=>({...p,model:n.target.value,effort:""})),options:[{value:"",label:"Ikuti default"},...ce(q).map(n=>({value:n.id,label:n.label}))]})}),e.jsx(P,{label:"Effort",children:e.jsx(O,{"aria-label":"Effort",value:i.effort,disabled:!i.agent,onChange:n=>S(p=>({...p,effort:n.target.value})),options:[{value:"",label:"Ikuti default"},..._e(q,i.model||ce(q)[0].id).map(n=>({value:n,label:n}))]})})]})]})]})}),m]})}const we=5e3,ne=10,ua=["antre","berjalan","riwayat","cron","setelan"],ha=["done","failed","canceled"],ue={done:"Selesai",failed:"Gagal",canceled:"Dibatalkan"},ma={tinggi:"err",sedang:"warn",rendah:"neutral"},pa=[{value:"butuh-keputusan",label:"Berhenti dan minta keputusan dulu"},{value:"full-control",label:"Jalan sampai selesai tanpa berhenti"}],he=a=>{var s;return(s=a.detail)==null?void 0:s.error};function ba(a,s){var t;return((t=s.find(r=>r.id===a))==null?void 0:t.title)??a}function K({specId:a,ctx:s}){return e.jsx("span",{className:"hn-sched-row-title",children:ba(a,s.backlog)})}function ja({q:a,ctx:s,busy:t,onCancel:r}){return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"ban",disabled:t,onClick:()=>r(a.id),children:"Batalkan"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsx(Q,{tone:ma[a.priority]??"neutral",size:"sm",children:_(Ve,a.priority)})]}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",_(J,a.source),a.note?` · ${a.note}`:""]})]})})}function xa({s:a,ctx:s,onGotoTerminal:t}){const r=a.flow?Xe[a.flow]??a.flow:"";return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"terminal",onClick:()=>t(a.id),children:"Buka terminal"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx(K,{specId:a.specId,ctx:s}),a.decision&&e.jsx(Q,{tone:"warn",icon:"bell",size:"sm",children:"menunggu kamu"})]}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId),r?` · ${r}`:""]})]})})}function ka({q:a,ctx:s,onToast:t}){const r=qe(a.specId);return e.jsx(D,{actions:e.jsxs(e.Fragment,{children:[e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"external-link",onClick:()=>window.open(r,"_blank","noreferrer"),children:"Buka review"}),e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"copy",onClick:()=>{var k;(k=navigator.clipboard)==null||k.writeText(r),t("Link review disalin","ok","copy")},children:"Salin"})]}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",_(J,a.source)," · ",a.launchedAt?`selesai ${ye(a.launchedAt)}`:a.note??"tidak diluncurkan"]})]})})}function ga({q:a,ctx:s,onRequeue:t,busy:r}){return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"secondary",leftIcon:"rotate-ccw",disabled:r,onClick:()=>t(a.id),children:"Antre ulang"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",a.note??"gagal tanpa alasan tercatat"]})]})})}function va({q:a,ctx:s,onRequeue:t,busy:r}){return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"rotate-ccw",disabled:r,onClick:()=>t(a.id),children:"Antre lagi"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",_(J,a.source)," · ",a.note??"dibatalkan"]})]})})}function Se({what:a,status:s,count:t,empty:r,render:k}){const[m,b]=o.useState([]),[d,g]=o.useState(0),[j,v]=o.useState(!1),[w,u]=o.useState(null),[l,c]=T("scheduler",`queue-${s}-page`,1,je),x=o.useCallback(()=>{I.getSchedulerQueue({status:s,page:l,limit:ne}).then(N=>{b(N.items),g(N.total),u(null),v(!0)}).catch(N=>{u(L(`memuat ${a}`,N)),v(!0)})},[s,l,a]);if(o.useEffect(()=>{x()},[x]),ve({topic:"schedulerQueue",params:{status:s,page:l,limit:ne},apply:N=>{b(N.data.items),g(N.data.total),u(null),v(!0)},refetch:()=>{x()},pollMs:we}),w)return e.jsx(V,{message:w,onRetry:x});if(t===0)return e.jsx("p",{className:"hn-sched-empty",children:r});if(!j)return e.jsx(G,{rows:3,label:`Memuat ${a}…`});const E=ke(d,l,ne);return e.jsxs(e.Fragment,{children:[e.jsx(Z,{label:a,children:m.map(N=>k(N))}),e.jsx(xe,{page:E.page,pageCount:E.pageCount,total:d,from:E.from,to:E.to,onPage:c,unit:"item"})]})}function fa({counts:a,ctx:s,busyId:t,onRowAction:r,onToast:k}){const m=ha.filter(u=>(a[u]??0)>0),b=(a.failed??0)>0?"failed":(a.done??0)>0?"done":"canceled",[d,g]=T("scheduler","riwayatStatus",b,ge("done","failed","canceled"));if(m.length===0)return e.jsx("p",{className:"hn-sched-empty",children:"Belum ada riwayat."});const j=m.includes(d)?d:m[0],v=u=>void r(u,"requeue"),w=u=>{const l=t===u.id;return j==="done"?e.jsx(ka,{q:u,ctx:s,onToast:k},u.id):j==="failed"?e.jsx(ga,{q:u,ctx:s,onRequeue:v,busy:l},u.id):e.jsx(va,{q:u,ctx:s,onRequeue:v,busy:l},u.id)};return e.jsxs(e.Fragment,{children:[e.jsx("div",{role:"group","aria-label":"Filter riwayat",className:"hn-sched-chips",children:m.map(u=>e.jsxs("button",{type:"button",className:"hn-sched-chip hn-touch-target","aria-pressed":u===j,onClick:()=>g(u),children:[ue[u],e.jsx("span",{className:"hn-sched-chip-count",children:a[u]})]},u))}),e.jsx(Se,{what:`item ${ue[j].toLowerCase()}`,status:j,count:a[j]??0,empty:"Belum ada riwayat.",render:w},j)]})}function ya({cfg:a,cap:s,liveCount:t,onWrite:r,onAsk:k,busy:m}){const b=a.enabled?a.paused?{status:"paused",label:"Dijeda"}:{status:"running",label:"Berjalan"}:{status:"stopped",label:"Berhenti"},d=t>=s;return e.jsxs("section",{"aria-label":"Status scheduler",className:"hn-sched-strip",children:[e.jsx(Ke,{status:b.status,variant:"dot",children:b.label}),e.jsx("div",{className:"hn-sched-capacity",children:e.jsx(Ye,{value:t,max:Math.max(s,1),size:"sm",tone:d?"warn":"brass",label:`${t} dari ${s} sesi`})}),e.jsxs("div",{className:"hn-sched-limits",children:[e.jsx(We,{}),e.jsx(Ze,{})]}),e.jsx(ea,{}),e.jsxs("div",{className:"hn-sched-strip-actions",children:[a.enabled?a.paused?e.jsx(C,{size:"sm",leftIcon:"play",disabled:m,onClick:()=>r({...a,paused:!1},"Scheduler dilanjutkan"),children:"Lanjutkan"}):e.jsx(C,{size:"sm",variant:"secondary",leftIcon:"pause",disabled:m,onClick:()=>k({...a,paused:!0},"jeda"),children:"Jeda"}):e.jsx(C,{size:"sm",leftIcon:"play",disabled:m,onClick:()=>r({...a,enabled:!0},"Scheduler diaktifkan"),children:"Aktifkan"}),a.enabled&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"hn-sched-strip-divider","aria-hidden":"true"}),e.jsx(C,{size:"sm",variant:"danger",leftIcon:"square",disabled:m,onClick:()=>k({...a,enabled:!1},"hentikan"),children:"Hentikan"})]})]})]})}function wa({status:a}){return e.jsxs("div",{"aria-label":"Status pemeriksaan peluncuran",className:"hn-sched-guard-status",children:[e.jsxs("div",{children:["Pemeriksaan ",a.enabled?"aktif":"nonaktif"," · ",a.liveCount," dari batas ",a.maxConcurrent," sesi berjalan (",a.liveAgentCount," di antaranya agen)"]}),e.jsxs("div",{children:["Beban CPU per inti: ",a.loadStatus==="available"&&a.loadPerCore!==null?a.loadPerCore.toFixed(2):"tidak tersedia",a.loadStatus==="unsupported"?" (tidak didukung platform)":""," · batas ",a.maxLoadPerCore]}),e.jsxs("div",{children:["Memori bebas: ",a.memStatus==="available"&&a.memAvailablePct!==null?`${a.memAvailablePct.toFixed(0)}%`:"tidak tersedia"," · minimal ",a.minMemAvailablePct,"%"]}),e.jsx("div",{className:"hn-sched-note",children:"Berlaku juga saat scheduler berhenti. Terminal dan shell tetap bisa dibuka, dan keduanya ikut dihitung dalam batas sesi."})]})}const se=a=>{const s=a.launchGuard??fe.launchGuard;return{maxConcurrent:String(a.maxConcurrent),autonomy:a.autonomy,guardOn:s.enabled,maxLoad:String(s.maxLoadPerCore),minMem:String(s.minMemAvailablePct),sources:{backlog:{enabled:a.sources.backlog.enabled,everyMin:String(a.sources.backlog.everyMin)},triase:{enabled:a.sources.triase.enabled,everyMin:String(a.sources.triase.everyMin)}}}},me=(a,s)=>{const t=s.launchGuard??fe.launchGuard,r=s.sources.backlog,k=s.sources.triase;return{...s,maxConcurrent:H(a.maxConcurrent,1,1/0,s.maxConcurrent),autonomy:a.autonomy,launchGuard:{...t,enabled:a.guardOn,maxLoadPerCore:H(a.maxLoad,.1,1/0,t.maxLoadPerCore,!1),minMemAvailablePct:H(a.minMem,0,100,t.minMemAvailablePct,!1)},sources:{...s.sources,backlog:{...r,enabled:a.sources.backlog.enabled,everyMin:H(a.sources.backlog.everyMin,1,1/0,r.everyMin)},triase:{...k,enabled:a.sources.triase.enabled,everyMin:H(a.sources.triase.everyMin,1,1/0,k.everyMin)}}}},Sa=a=>`${a.lastRunAt?`terakhir ${ye(a.lastRunAt)}`:"belum pernah dicek"} · ${a.nextRunAt?`berikutnya ${ta(a.nextRunAt)}`:"belum dijadwalkan"}`;function Ca({cfg:a,sources:s,admission:t,onWrite:r,busy:k}){const{draft:m,setDraft:b,dirty:d}=sa(se(a)),g=l=>se(me(l,a)),j=()=>b(l=>g(l)),v=()=>{const l=me(m,a);b(se(l)),r(l)},w=l=>{l.key==="Enter"&&(l.preventDefault(),v())},u=(l,c)=>b(x=>({...x,sources:{...x.sources,[l]:{...x.sources[l],...c}}}));return e.jsxs("div",{className:"hn-sched-panel",children:[e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-sesi",children:[e.jsx("h3",{id:"sched-set-sesi",className:"hn-sched-group-title",children:"Sesi"}),e.jsxs("div",{className:"hn-sched-grid",children:[e.jsx(P,{label:"Batas sesi bersamaan",hint:"Termasuk terminal dan shell yang kamu buka sendiri.",children:e.jsx(M,{type:"number",min:1,value:m.maxConcurrent,"aria-label":"Batas sesi bersamaan",placeholder:"mis. 6",onChange:l=>b(c=>({...c,maxConcurrent:l.target.value})),onBlur:j,onKeyDown:w})}),e.jsx(P,{label:"Saat ada keputusan yang belum jelas",hint:"Keputusan yang ambigu tetap ditanyakan ke lead atau kamu.",children:e.jsx(O,{value:m.autonomy,"aria-label":"Mode otonomi",onChange:l=>b(c=>({...c,autonomy:l.target.value})),options:pa})})]})]}),e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-peluncuran",children:[e.jsx("h3",{id:"sched-set-peluncuran",className:"hn-sched-group-title",children:"Peluncuran"}),e.jsx(te,{label:"Tahan peluncuran saat server sibuk",checked:m.guardOn,onChange:l=>b(c=>({...c,guardOn:l}))}),e.jsx("p",{className:"hn-sched-group-hint",children:"Mencegah sesi baru diluncurkan saat batas sesi penuh, beban CPU per inti terlalu tinggi, atau memori bebas terlalu sedikit. Berlaku juga untuk peluncuran manual. Mematikannya melewati ketiga pemeriksaan itu. Terpisah dari saklar scheduler dan sumber."}),e.jsxs("div",{className:"hn-sched-grid",children:[e.jsx(P,{label:"Batas beban CPU per inti",hint:"Di atas angka ini, sesi baru tidak diluncurkan.",children:e.jsx(M,{type:"number",min:.1,step:"any",value:m.maxLoad,"aria-label":"Batas beban CPU per inti",placeholder:"mis. 2.5",onChange:l=>b(c=>({...c,maxLoad:l.target.value})),onBlur:j,onKeyDown:w})}),e.jsx(P,{label:"Memori bebas minimal (%)",hint:"Di bawah angka ini, sesi baru tidak diluncurkan.",children:e.jsx(M,{type:"number",min:0,max:100,step:"any",value:m.minMem,"aria-label":"Memori bebas minimal (%)",placeholder:"mis. 15",onChange:l=>b(c=>({...c,minMem:l.target.value})),onBlur:j,onKeyDown:w})})]}),t&&e.jsx(wa,{status:t})]}),e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-sumber",children:[e.jsx("h3",{id:"sched-set-sumber",className:"hn-sched-group-title",children:"Sumber otomatis"}),["backlog","triase"].map(l=>{const c=s.find(x=>x.id===l);return e.jsxs("div",{className:"hn-sched-source",children:[e.jsx(te,{label:J[l],checked:m.sources[l].enabled,onChange:x=>u(l,{enabled:x})}),e.jsx("span",{className:"hn-sched-spacer"}),e.jsxs("label",{className:"hn-sched-inline-field",children:["cek tiap",e.jsx(M,{type:"number",min:1,"aria-label":`Interval cek ${J[l]}`,placeholder:"mis. 30",value:m.sources[l].everyMin,onChange:x=>u(l,{everyMin:x.target.value}),onBlur:j,onKeyDown:w}),"menit"]}),c&&e.jsx("span",{className:"hn-sched-source-facts",children:Sa(c)})]},l)})]}),e.jsxs("div",{className:"hn-sched-savebar",children:[d&&e.jsx("span",{role:"status",className:"hn-sched-note",children:"Ada perubahan yang belum disimpan."}),e.jsx(C,{leftIcon:"save",disabled:k,onClick:v,children:"Simpan setelan"})]})]})}function Na({projects:a,onToggle:s,busyId:t}){return e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-project",children:[e.jsx("h3",{id:"sched-set-project",className:"hn-sched-group-title",children:"Project yang diizinkan"}),e.jsx("p",{className:"hn-sched-group-hint",children:"Scheduler hanya menyentuh project yang diizinkan. Default: tidak diizinkan."}),a.length===0?e.jsx("p",{className:"hn-sched-empty",children:"Belum ada project."}):e.jsx(Z,{label:"Project yang diizinkan",children:a.map(r=>e.jsx(D,{actions:r.schedulerOptIn?e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"ban",disabled:t===r.id,onClick:()=>s(r.id,!1),children:"Cabut izin"}):e.jsx(C,{size:"sm",leftIcon:"check",disabled:t===r.id,onClick:()=>s(r.id,!0),children:"Izinkan"}),children:e.jsx("span",{className:"hn-sched-row-text",children:e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx("span",{className:"hn-sched-row-title",children:r.name}),e.jsx(Q,{tone:r.schedulerOptIn?"ok":"neutral",size:"sm",children:r.schedulerOptIn?"diizinkan":"tidak diizinkan"})]})})},r.id))})]})}function Ia(a){const[s,t]=o.useState(null),[r,k]=o.useState(null),m=o.useCallback(()=>{I.getSettings().then(d=>{t(d),k(null)}).catch(d=>k(L("memuat orkestrasi",d)))},[]);o.useEffect(()=>{m()},[m]);const b=o.useCallback(async(d,g)=>{if(!s)return;const j=s;t({...j,orchestration:d});try{const v=await I.getSettings().catch(()=>{});await I.putSettings(ra(j,{...j,orchestration:d},v)),a(g,"ok","check-circle-2")}catch(v){t(j),a(L("menyimpan orkestrasi",v),"err","alert-triangle")}},[s,a]);return{setting:s,error:r,load:m,writeOrchestration:b}}function Pa({snap:a}){return e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-orkestrasi",children:[e.jsx("h3",{id:"sched-set-orkestrasi",className:"hn-sched-group-title",children:"Orkestrasi subagen per fase"}),e.jsx("p",{className:"hn-sched-group-hint",children:"Perubahan tersimpan saat diubah. Buka satu flow untuk mengatur model dan effort per fase."}),a.error?e.jsx(V,{message:a.error,onRetry:a.load}):a.setting?e.jsx(la,{variant:"accordion",orchestration:a.setting.orchestration,onChange:(s,t)=>void a.writeOrchestration(s,t)}):e.jsx(G,{rows:2,label:"Memuat orkestrasi…"})]})}function $a({projects:a,backlog:s,onProjectChanged:t,onToast:r,onGotoTerminal:k}){const{confirm:m,dialog:b}=pe(),[d,g]=o.useState(null),[j,v]=o.useState("loading"),[w,u]=o.useState(!1),[l,c]=o.useState(null),[x,E]=T("scheduler","tab","antre",ge(...ua)),N=Ia(r),i=o.useCallback((h=!1)=>{h||v("loading"),I.getSchedulerState().then(f=>{g(f),v("ready")}).catch(()=>{h||v("error")})},[]);o.useEffect(()=>{i()},[i]),ve({topic:"schedulerState",params:{},apply:h=>{g(h.state),v("ready")},refetch:()=>i(!0),pollMs:we});const S=o.useCallback(async(h,f="Setelan scheduler tersimpan")=>{u(!0);try{await I.putSchedulerConfig(h),r(f,"ok","save"),i(!0)}catch(y){r(he(y)??L("menyimpan setelan",y),"err","x-circle")}finally{u(!1)}},[i,r]),X=o.useCallback((h,f)=>{const y=f==="jeda";m({title:y?"Jeda scheduler?":"Hentikan scheduler?",eyebrow:"scheduler · rem darurat",message:y?"Scheduler berhenti meluncurkan sesi baru dari antrean sampai kamu melanjutkannya. Sesi yang sudah berjalan tidak dihentikan.":void 0,impact:y?void 0:["Sumber backlog dan triase tidak lagi diperiksa sampai diaktifkan lagi.","Antrean tetap tersimpan dan tidak diproses selama berhenti.","Sesi yang sudah berjalan tetap berjalan."],confirmLabel:y?"Jeda scheduler":"Hentikan scheduler",icon:y?"pause":"square",tone:y?"default":"danger",run:()=>S(h,y?"Scheduler dijeda":"Scheduler dihentikan")})},[m,S]),Y=o.useCallback(async(h,f)=>{c(h);try{await I.updateProject(h,{schedulerOptIn:f}),await t(h),r(f?"Project diizinkan untuk scheduler":"Izin scheduler dicabut","ok")}catch(y){r(L("mengubah izin project",y),"err","x-circle")}finally{c(null)}},[t,r]),F=o.useCallback(async(h,f)=>{c(h);try{f==="cancel"?(await I.cancelSchedulerQueueItem(h),r("Item antrean dibatalkan","ok","ban")):(await I.requeueSchedulerQueueItem(h),r("Item dikembalikan ke antrean","ok","rotate-ccw"))}catch(y){const U=f==="cancel"?"membatalkan item antrean":"mengembalikan item ke antrean";r(he(y)??L(U,y),"err","x-circle")}finally{c(null),i(!0)}},[i,r]);if(j==="loading")return e.jsx(G,{rows:4,label:"Memuat scheduler…"});if(j==="error"||!d)return e.jsx(Qe,{kind:"error",hint:"Gagal memuat state scheduler.",action:()=>i(),actionLabel:"Coba lagi"});const R={backlog:s,projectName:h=>{var f;return((f=a.find(y=>y.id===h))==null?void 0:f.name)??"Project lain"}},A=d.queueCounts,z=(A.done??0)+(A.failed??0)+(A.canceled??0),B=[{value:"antre",label:"Antre",count:A.queued||void 0},{value:"berjalan",label:"Berjalan",count:d.sessions.length||void 0},{value:"riwayat",label:"Riwayat",count:z||void 0},{value:"cron",label:"Cron"},{value:"setelan",label:"Setelan"}];return e.jsxs("div",{className:"hn-sched",children:[e.jsx(ya,{cfg:d.config,cap:d.cap,liveCount:d.liveCount,onWrite:S,onAsk:X,busy:w}),e.jsxs(be,{tabs:B,value:x,onChange:h=>E(h),children:[e.jsx($,{value:"antre",className:"hn-sched-panel",children:e.jsx(Se,{what:"antrean",status:"queued",count:A.queued,empty:"Antrean kosong.",render:h=>e.jsx(ja,{q:h,ctx:R,busy:l===h.id,onCancel:f=>void F(f,"cancel")},h.id)})}),e.jsx($,{value:"berjalan",className:"hn-sched-panel",children:d.sessions.length===0?e.jsx("p",{className:"hn-sched-empty",children:"Tidak ada sesi dari scheduler yang sedang berjalan."}):e.jsx(Z,{label:"Sesi berjalan",children:d.sessions.map(h=>e.jsx(xa,{s:h,ctx:R,onGotoTerminal:k},h.id))})}),e.jsx($,{value:"riwayat",className:"hn-sched-panel",children:x==="riwayat"&&e.jsx(fa,{counts:A,ctx:R,busyId:l,onRowAction:F,onToast:r})}),e.jsx($,{value:"cron",className:"hn-sched-panel",children:x==="cron"&&e.jsx(oa,{projects:a,onProjectChanged:t,onToast:r,timeZone:d.serverTimeZone})}),e.jsxs($,{value:"setelan",className:"hn-sched-panel",children:[e.jsx(Ca,{cfg:d.config,sources:d.sources,admission:d.admission,onWrite:h=>void S(h),busy:w}),e.jsx(Na,{projects:a,onToggle:Y,busyId:l}),e.jsx(Pa,{snap:N})]})]}),b]})}export{$a as SchedulerScreen};
1
+ import{d as pe,q as T,D as Re,W as Be,h as I,i as L,aZ as Me,a_ as ze,j as e,g as O,B as C,I as Oe,L as G,aJ as $e,n as Q,a$ as He,O as De,M as Fe,c as be,aW as $,e as P,f as M,b0 as Te,H as Ue,b1 as te,b2 as ce,a9 as _e,b3 as Je,b4 as W,V as je,R as Z,X as D,l as _,b5 as Ge,a2 as xe,Z as ke,r as ge,G as ve,m as Qe,Y as Ke,b6 as Ye,b7 as We,b8 as Ze,P as Ve,b9 as J,F as Xe,ba as fe,_ as qe}from"./index-Av-RfHXX.js";import{R as o}from"./react-DfGhg7ZW.js";import{L as ea}from"./live-Bfx0Oehi.js";import"./markdown-CWEY34jk.js";import{b as aa,I as V,c as H,f as na,u as sa,a as ye,d as ta}from"./sched-lead-shared-DJn2D3VE.js";/* empty css */import{r as ra,O as la}from"./settings-rebase-Bbz53ceL.js";import"./xterm-3VOAfa_q.js";const de=10,ee=a=>{var s;return(s=a.detail)==null?void 0:s.error},ae=a=>String(a).padStart(2,"0"),oe=a=>{const s={name:(a==null?void 0:a.name)??"",prompt:(a==null?void 0:a.prompt)??"",enabled:(a==null?void 0:a.enabled)??!1,kind:"lanjutan",time:"07:00",weekday:1,everyHours:"6",expr:(a==null?void 0:a.expr)??"0 7 * * *",agent:(a==null?void 0:a.agent)??"",model:(a==null?void 0:a.model)??"",effort:(a==null?void 0:a.effort)??""},t=a?Je(a.expr):{kind:"harian",hour:7,minute:0};if(!t)return s;if(t.kind==="tiap-n-jam")return{...s,kind:t.kind,everyHours:String(t.everyHours),time:`00:${ae(t.minute)}`};const r=`${ae(t.hour)}:${ae(t.minute)}`;return t.kind==="mingguan"?{...s,kind:t.kind,time:r,weekday:t.weekday}:{...s,kind:t.kind,time:r}},ia=a=>{if(a.kind==="lanjutan")return a.expr.trim();const[s,t]=a.time.split(":").map(Number);switch(a.kind){case"harian":return W({kind:"harian",hour:s,minute:t});case"hari-kerja":return W({kind:"hari-kerja",hour:s,minute:t});case"mingguan":return W({kind:"mingguan",hour:s,minute:t,weekday:a.weekday});case"tiap-n-jam":return W({kind:"tiap-n-jam",everyHours:H(a.everyHours,1,23,6),minute:t})}},ca={launched:"ok",queued:"neutral",skipped:"warn",failed:"err"};function da({cronId:a,at:s}){const[t,r]=o.useState([]),[k,m]=o.useState(0),[b,d]=o.useState(!1),[g,j]=o.useState(null),[v,w]=T("scheduler","cronRunsPage",1,je),u=o.useCallback(()=>{let c=!0;return I.listCronRuns(a,{page:v,limit:de}).then(x=>{c&&(r(x.items),m(x.total),d(!0),j(null))}).catch(x=>{c&&(j(L("memuat riwayat",x)),d(!0))}),()=>{c=!1}},[a,v]);if(o.useEffect(()=>u(),[u]),g)return e.jsx(V,{message:g,onRetry:()=>{u()}});if(!b)return e.jsx(G,{rows:2,label:"Memuat riwayat…"});if(k===0)return e.jsx("p",{className:"hn-sched-empty",children:"Belum ada eksekusi."});const l=ke(k,v,de);return e.jsxs(e.Fragment,{children:[e.jsx(Z,{label:"Riwayat eksekusi",children:t.map(c=>e.jsx(D,{children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx("span",{className:"hn-sched-row-head",children:e.jsx(Q,{tone:ca[c.status]??"neutral",size:"sm",children:_(Ge,c.status)})}),e.jsxs("span",{className:"hn-sched-row-meta",children:["jatuh tempo ",s(c.dueAt),c.startedAt?` · mulai ${s(c.startedAt)}`:"",c.manual?" · uji coba":"",c.note?` · ${c.note}`:""]})]})},c.id))}),e.jsx(xe,{page:l.page,pageCount:l.pageCount,total:k,from:l.from,to:l.to,onPage:w,unit:"run"})]})}function oa({projects:a,onProjectChanged:s,onToast:t,timeZone:r}){var ie;const{confirm:k,dialog:m}=pe(),b=r??aa(),d=n=>na(n,b),[g,j]=T("scheduler","cronProject",((ie=a[0])==null?void 0:ie.id)??"",Re),[v,w]=o.useState([]),[u,l]=o.useState(!1),[c,x]=o.useState(null),[E,N]=o.useState(void 0),[i,S]=o.useState(oe()),[X,Y]=o.useState("dasar"),[F,re]=T("scheduler","cronOpenRuns",null,Be),[R,A]=o.useState(!1),z=a.find(n=>n.id===g),B=o.useCallback(()=>{if(!g){w([]),x(null),l(!0);return}I.listCrons({projectId:g,page:1,limit:100}).then(n=>{w(n.items),x(null),l(!0)}).catch(n=>{x(L("memuat daftar cron",n)),l(!0)})},[g]);o.useEffect(()=>{w([]),l(!1),B()},[B]);const h=n=>{N(n??null),S(oe(n)),Y("dasar")},f=ia(i),y=Me(f)!==null,U=y?ze(f,new Date,b):null,Ce=async()=>{if(!y){t("Ekspresi cron tidak sah","err","x-circle");return}A(!0);try{E?await I.patchCron(E.id,{name:i.name,expr:f,prompt:i.prompt,enabled:i.enabled,agent:i.agent||null,model:i.model||null,effort:i.effort||null}):await I.createCron({project:g,name:i.name,expr:f,prompt:i.prompt,enabled:i.enabled,agent:i.agent||void 0,model:i.model||void 0,effort:i.effort||void 0}),t("Cron tersimpan","ok","save"),N(void 0),B()}catch(n){t(ee(n)??L("menyimpan cron",n),"err","x-circle")}finally{A(!1)}},Ne=async n=>{A(!0);try{await I.runCronNow(n),t("Uji coba masuk antrean; sesi dibuka pada siklus berikutnya","ok","play")}catch(p){t(ee(p)??L("menjalankan cron",p),"err","x-circle")}finally{A(!1),B()}},Ie=async n=>{A(!0);try{await I.deleteCron(n),t("Cron dihapus","ok","trash")}catch(p){t(ee(p)??L("menghapus cron",p),"err","x-circle")}finally{A(!1),B()}},Pe=n=>{k({title:"Hapus cron ini?",eyebrow:"scheduler · cronjob",impact:[`Cron "${n.name}" di project ${(z==null?void 0:z.name)??"ini"} dihapus permanen.`,"Jadwalnya berhenti dan tidak akan dijalankan lagi.","Tindakan ini tidak bisa dibatalkan."],confirmLabel:"Hapus cron",icon:"trash-2",tone:"danger",run:()=>Ie(n.id)})},Ae=async()=>{if(g)try{await I.updateProject(g,{schedulerOptIn:!0}),await s(g),t("Project diizinkan untuk scheduler","ok")}catch(n){t(L("mengizinkan project",n),"err","x-circle")}},Le=n=>[{key:"edit",label:"Ubah",icon:"pencil",onSelect:()=>h(n)},{key:"run",label:"Jalankan sekarang",icon:"play",disabled:R,onSelect:()=>void Ne(n.id)},{key:"runs",label:F===n.id?"Sembunyikan riwayat":"Riwayat",icon:"list",onSelect:()=>re(F===n.id?null:n.id)},{key:"remove",label:"Hapus",icon:"trash",tone:"danger",disabled:R,onSelect:()=>Pe(n)}],q=i.agent||"claude",le=()=>S(n=>({...n,everyHours:String(H(n.everyHours,1,23,6))})),Ee=y?U?`Perkiraan jalan berikutnya: ${d(U.toISOString())}`:`Preview belum bisa dihitung untuk zona ${b}. Jam jalan berikutnya tampil di daftar cron.`:"Jadwal tidak sah, jadi tidak ada jalan berikutnya.";return e.jsxs("div",{className:"hn-sched-panel",children:[e.jsxs("div",{className:"hn-sched-toolbar",children:[e.jsx(O,{value:g,"aria-label":"Project",onChange:n=>j(n.target.value),options:a.map(n=>({value:n.id,label:n.name}))}),e.jsx(C,{size:"sm",leftIcon:"plus",disabled:!g,onClick:()=>h(),children:"Cron baru"})]}),e.jsxs("p",{className:"hn-sched-caption",children:["Jam ditampilkan dalam zona server ",e.jsx("b",{children:b}),r===void 0?" (server belum melaporkan zonanya, jadi zona browser yang dipakai)":"","."]}),z&&!z.schedulerOptIn&&e.jsx("div",{className:"hn-sched-notice",children:e.jsxs("div",{className:"hn-dense-row",role:"note",children:[e.jsx(Oe,{name:"alert-triangle",size:16,color:"var(--clay-600)"}),e.jsx("span",{className:"hn-grow hn-sched-notice-text",children:"Project ini belum diizinkan untuk scheduler, jadi cron-nya tidak akan pernah dijalankan."}),e.jsx(C,{size:"sm",leftIcon:"check",onClick:()=>void Ae(),children:"Aktifkan scheduler di project ini"})]})}),c?e.jsx(V,{message:c,onRetry:B,busy:R}):u?v.length===0?e.jsx("p",{className:"hn-sched-empty",children:"Belum ada cron di project ini."}):e.jsx($e,{children:e.jsxs("table",{className:"hn-sched-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{scope:"col",children:"Cron"}),e.jsx("th",{scope:"col",children:"Jadwal"}),e.jsx("th",{scope:"col",children:"Terakhir"}),e.jsx("th",{scope:"col",children:"Berikutnya"}),e.jsx("th",{scope:"col",children:e.jsx("span",{className:"hn-sr-only",children:"Aksi"})})]})}),e.jsx("tbody",{children:v.map(n=>e.jsxs(o.Fragment,{children:[e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Cron",children:e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx("span",{className:"hn-sched-row-title",children:n.name}),e.jsx(Q,{tone:n.enabled?"ok":"neutral",size:"sm",children:n.enabled?"aktif":"nonaktif"})]})}),e.jsx("td",{"data-label":"Jadwal",children:He(n.expr)}),e.jsx("td",{"data-label":"Terakhir",children:d(n.lastRunAt)}),e.jsx("td",{"data-label":"Berikutnya",children:d(n.nextRunAt)}),e.jsx("td",{className:"hn-sched-cell-actions",children:e.jsx(De,{label:`Aksi untuk cron ${n.name}`,title:n.name,items:Le(n)})})]}),F===n.id&&e.jsx("tr",{className:"hn-sched-runs",children:e.jsx("td",{colSpan:5,children:e.jsx("div",{id:`cron-runs-${n.id}`,children:e.jsx(da,{cronId:n.id,at:d})})})})]},n.id))})]})}):e.jsx(G,{rows:3,label:"Memuat daftar cron…"}),e.jsx(Fe,{open:E!==void 0,title:E?"Ubah cron":"Cron baru",eyebrow:"scheduler",onClose:()=>N(void 0),width:640,footer:e.jsxs("div",{className:"hn-sched-savebar",children:[e.jsx(C,{size:"sm",variant:"ghost",onClick:()=>N(void 0),children:"Batal"}),e.jsx(C,{size:"sm",leftIcon:"save",disabled:R,onClick:()=>void Ce(),children:"Simpan"})]}),children:e.jsxs(be,{tabs:[{value:"dasar",label:"Dasar"},{value:"lanjutan",label:"Lanjutan"}],value:X,onChange:n=>Y(n),children:[e.jsxs($,{value:"dasar",className:"hn-sched-panel",children:[e.jsx(P,{label:"Nama cron",children:e.jsx(M,{"aria-label":"Nama cron",placeholder:"mis. Cek error produksi pagi",value:i.name,onChange:n=>S(p=>({...p,name:n.target.value}))})}),e.jsxs("div",{className:"hn-sched-form-grid",children:[e.jsx(P,{label:"Preset jadwal",children:e.jsx(O,{"aria-label":"Preset jadwal",value:i.kind,onChange:n=>S(p=>({...p,kind:n.target.value})),options:[{value:"harian",label:"Setiap hari"},{value:"hari-kerja",label:"Hari kerja"},{value:"mingguan",label:"Mingguan"},{value:"tiap-n-jam",label:"Tiap N jam"},{value:"lanjutan",label:"Ekspresi cron (lanjutan)"}]})}),i.kind!=="lanjutan"&&e.jsx(P,{label:i.kind==="tiap-n-jam"?"Menit pada setiap jam":"Jam",children:e.jsx(M,{type:"time","aria-label":"Jam",value:i.time,onChange:n=>S(p=>({...p,time:n.target.value}))})}),i.kind==="mingguan"&&e.jsx(P,{label:"Hari",children:e.jsx(O,{"aria-label":"Hari",value:String(i.weekday),onChange:n=>S(p=>({...p,weekday:Number(n.target.value)})),options:Te.map((n,p)=>({value:String(p),label:n}))})}),i.kind==="tiap-n-jam"&&e.jsx(P,{label:"Tiap berapa jam",children:e.jsx(M,{type:"number",min:1,max:23,"aria-label":"Tiap berapa jam",placeholder:"mis. 6",value:i.everyHours,onChange:n=>S(p=>({...p,everyHours:n.target.value})),onBlur:le,onKeyDown:n=>{n.key==="Enter"&&(n.preventDefault(),le())}})})]}),i.kind==="lanjutan"&&e.jsx(P,{label:"Ekspresi cron",hint:"Lima bagian: menit, jam, tanggal, bulan, hari dalam minggu.",children:e.jsx(M,{"aria-label":"Ekspresi cron",placeholder:"mis. 0 7 * * 1-5",value:i.expr,onChange:n=>S(p=>({...p,expr:n.target.value}))})}),e.jsx("p",{"data-testid":"cron-next-preview",className:`hn-sched-note${U?"":" hn-sched-preview-warn"}`,children:Ee}),e.jsxs("p",{className:"hn-sched-note",children:["Jadwal berlaku menurut zona waktu server ",e.jsx("b",{children:b}),"."]}),e.jsx(P,{label:"Prompt",hint:"Instruksi bebas untuk agen. Temuan sebaiknya dicatat sebagai item backlog baru.",children:e.jsx(Ue,{"aria-label":"Prompt",rows:6,placeholder:"mis. Periksa error 5xx sejak kemarin, lalu catat temuannya sebagai QA finding.",value:i.prompt,onChange:n=>S(p=>({...p,prompt:n.target.value}))})}),e.jsx(te,{label:"Aktif",checked:i.enabled,onChange:n=>S(p=>({...p,enabled:n}))})]}),e.jsxs($,{value:"lanjutan",className:"hn-sched-panel",children:[e.jsx("p",{className:"hn-sched-group-hint",children:"Kosongkan untuk mengikuti default sesi. Model dan effort baru tersedia setelah runtime dipilih."}),e.jsxs("div",{className:"hn-sched-form-grid",children:[e.jsx(P,{label:"Runtime",children:e.jsx(O,{"aria-label":"Runtime",value:i.agent,onChange:n=>S(p=>({...p,agent:n.target.value,model:"",effort:""})),options:[{value:"",label:"Ikuti default sesi"},{value:"claude",label:"Claude Code"},{value:"codex",label:"Codex CLI"}]})}),e.jsx(P,{label:"Model",children:e.jsx(O,{"aria-label":"Model",value:i.model,disabled:!i.agent,onChange:n=>S(p=>({...p,model:n.target.value,effort:""})),options:[{value:"",label:"Ikuti default"},...ce(q).map(n=>({value:n.id,label:n.label}))]})}),e.jsx(P,{label:"Effort",children:e.jsx(O,{"aria-label":"Effort",value:i.effort,disabled:!i.agent,onChange:n=>S(p=>({...p,effort:n.target.value})),options:[{value:"",label:"Ikuti default"},..._e(q,i.model||ce(q)[0].id).map(n=>({value:n,label:n}))]})})]})]})]})}),m]})}const we=5e3,ne=10,ua=["antre","berjalan","riwayat","cron","setelan"],ha=["done","failed","canceled"],ue={done:"Selesai",failed:"Gagal",canceled:"Dibatalkan"},ma={tinggi:"err",sedang:"warn",rendah:"neutral"},pa=[{value:"butuh-keputusan",label:"Berhenti dan minta keputusan dulu"},{value:"full-control",label:"Jalan sampai selesai tanpa berhenti"}],he=a=>{var s;return(s=a.detail)==null?void 0:s.error};function ba(a,s){var t;return((t=s.find(r=>r.id===a))==null?void 0:t.title)??a}function K({specId:a,ctx:s}){return e.jsx("span",{className:"hn-sched-row-title",children:ba(a,s.backlog)})}function ja({q:a,ctx:s,busy:t,onCancel:r}){return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"ban",disabled:t,onClick:()=>r(a.id),children:"Batalkan"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsx(Q,{tone:ma[a.priority]??"neutral",size:"sm",children:_(Ve,a.priority)})]}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",_(J,a.source),a.note?` · ${a.note}`:""]})]})})}function xa({s:a,ctx:s,onGotoTerminal:t}){const r=a.flow?Xe[a.flow]??a.flow:"";return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"terminal",onClick:()=>t(a.id),children:"Buka terminal"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx(K,{specId:a.specId,ctx:s}),a.decision&&e.jsx(Q,{tone:"warn",icon:"bell",size:"sm",children:"menunggu kamu"})]}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId),r?` · ${r}`:""]})]})})}function ka({q:a,ctx:s,onToast:t}){const r=qe(a.specId);return e.jsx(D,{actions:e.jsxs(e.Fragment,{children:[e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"external-link",onClick:()=>window.open(r,"_blank","noreferrer"),children:"Buka review"}),e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"copy",onClick:()=>{var k;(k=navigator.clipboard)==null||k.writeText(r),t("Link review disalin","ok","copy")},children:"Salin"})]}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",_(J,a.source)," · ",a.launchedAt?`selesai ${ye(a.launchedAt)}`:a.note??"tidak diluncurkan"]})]})})}function ga({q:a,ctx:s,onRequeue:t,busy:r}){return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"secondary",leftIcon:"rotate-ccw",disabled:r,onClick:()=>t(a.id),children:"Antre ulang"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",a.note??"gagal tanpa alasan tercatat"]})]})})}function va({q:a,ctx:s,onRequeue:t,busy:r}){return e.jsx(D,{actions:e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"rotate-ccw",disabled:r,onClick:()=>t(a.id),children:"Antre lagi"}),children:e.jsxs("span",{className:"hn-sched-row-text",children:[e.jsx(K,{specId:a.specId,ctx:s}),e.jsxs("span",{className:"hn-sched-row-meta",children:[s.projectName(a.projectId)," · ",_(J,a.source)," · ",a.note??"dibatalkan"]})]})})}function Se({what:a,status:s,count:t,empty:r,render:k}){const[m,b]=o.useState([]),[d,g]=o.useState(0),[j,v]=o.useState(!1),[w,u]=o.useState(null),[l,c]=T("scheduler",`queue-${s}-page`,1,je),x=o.useCallback(()=>{I.getSchedulerQueue({status:s,page:l,limit:ne}).then(N=>{b(N.items),g(N.total),u(null),v(!0)}).catch(N=>{u(L(`memuat ${a}`,N)),v(!0)})},[s,l,a]);if(o.useEffect(()=>{x()},[x]),ve({topic:"schedulerQueue",params:{status:s,page:l,limit:ne},apply:N=>{b(N.data.items),g(N.data.total),u(null),v(!0)},refetch:()=>{x()},pollMs:we}),w)return e.jsx(V,{message:w,onRetry:x});if(t===0)return e.jsx("p",{className:"hn-sched-empty",children:r});if(!j)return e.jsx(G,{rows:3,label:`Memuat ${a}…`});const E=ke(d,l,ne);return e.jsxs(e.Fragment,{children:[e.jsx(Z,{label:a,children:m.map(N=>k(N))}),e.jsx(xe,{page:E.page,pageCount:E.pageCount,total:d,from:E.from,to:E.to,onPage:c,unit:"item"})]})}function fa({counts:a,ctx:s,busyId:t,onRowAction:r,onToast:k}){const m=ha.filter(u=>(a[u]??0)>0),b=(a.failed??0)>0?"failed":(a.done??0)>0?"done":"canceled",[d,g]=T("scheduler","riwayatStatus",b,ge("done","failed","canceled"));if(m.length===0)return e.jsx("p",{className:"hn-sched-empty",children:"Belum ada riwayat."});const j=m.includes(d)?d:m[0],v=u=>void r(u,"requeue"),w=u=>{const l=t===u.id;return j==="done"?e.jsx(ka,{q:u,ctx:s,onToast:k},u.id):j==="failed"?e.jsx(ga,{q:u,ctx:s,onRequeue:v,busy:l},u.id):e.jsx(va,{q:u,ctx:s,onRequeue:v,busy:l},u.id)};return e.jsxs(e.Fragment,{children:[e.jsx("div",{role:"group","aria-label":"Filter riwayat",className:"hn-sched-chips",children:m.map(u=>e.jsxs("button",{type:"button",className:"hn-sched-chip hn-touch-target","aria-pressed":u===j,onClick:()=>g(u),children:[ue[u],e.jsx("span",{className:"hn-sched-chip-count",children:a[u]})]},u))}),e.jsx(Se,{what:`item ${ue[j].toLowerCase()}`,status:j,count:a[j]??0,empty:"Belum ada riwayat.",render:w},j)]})}function ya({cfg:a,cap:s,liveCount:t,onWrite:r,onAsk:k,busy:m}){const b=a.enabled?a.paused?{status:"paused",label:"Dijeda"}:{status:"running",label:"Berjalan"}:{status:"stopped",label:"Berhenti"},d=t>=s;return e.jsxs("section",{"aria-label":"Status scheduler",className:"hn-sched-strip",children:[e.jsx(Ke,{status:b.status,variant:"dot",children:b.label}),e.jsx("div",{className:"hn-sched-capacity",children:e.jsx(Ye,{value:t,max:Math.max(s,1),size:"sm",tone:d?"warn":"brass",label:`${t} dari ${s} sesi`})}),e.jsxs("div",{className:"hn-sched-limits",children:[e.jsx(We,{}),e.jsx(Ze,{})]}),e.jsx(ea,{}),e.jsxs("div",{className:"hn-sched-strip-actions",children:[a.enabled?a.paused?e.jsx(C,{size:"sm",leftIcon:"play",disabled:m,onClick:()=>r({...a,paused:!1},"Scheduler dilanjutkan"),children:"Lanjutkan"}):e.jsx(C,{size:"sm",variant:"secondary",leftIcon:"pause",disabled:m,onClick:()=>k({...a,paused:!0},"jeda"),children:"Jeda"}):e.jsx(C,{size:"sm",leftIcon:"play",disabled:m,onClick:()=>r({...a,enabled:!0},"Scheduler diaktifkan"),children:"Aktifkan"}),a.enabled&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"hn-sched-strip-divider","aria-hidden":"true"}),e.jsx(C,{size:"sm",variant:"danger",leftIcon:"square",disabled:m,onClick:()=>k({...a,enabled:!1},"hentikan"),children:"Hentikan"})]})]})]})}function wa({status:a}){return e.jsxs("div",{"aria-label":"Status pemeriksaan peluncuran",className:"hn-sched-guard-status",children:[e.jsxs("div",{children:["Pemeriksaan ",a.enabled?"aktif":"nonaktif"," · ",a.liveCount," dari batas ",a.maxConcurrent," sesi berjalan (",a.liveAgentCount," di antaranya agen)"]}),e.jsxs("div",{children:["Beban CPU per inti: ",a.loadStatus==="available"&&a.loadPerCore!==null?a.loadPerCore.toFixed(2):"tidak tersedia",a.loadStatus==="unsupported"?" (tidak didukung platform)":""," · batas ",a.maxLoadPerCore]}),e.jsxs("div",{children:["Memori bebas: ",a.memStatus==="available"&&a.memAvailablePct!==null?`${a.memAvailablePct.toFixed(0)}%`:"tidak tersedia"," · minimal ",a.minMemAvailablePct,"%"]}),e.jsx("div",{className:"hn-sched-note",children:"Berlaku juga saat scheduler berhenti. Terminal dan shell tetap bisa dibuka, dan keduanya ikut dihitung dalam batas sesi."})]})}const se=a=>{const s=a.launchGuard??fe.launchGuard;return{maxConcurrent:String(a.maxConcurrent),autonomy:a.autonomy,guardOn:s.enabled,maxLoad:String(s.maxLoadPerCore),minMem:String(s.minMemAvailablePct),sources:{backlog:{enabled:a.sources.backlog.enabled,everyMin:String(a.sources.backlog.everyMin)},triase:{enabled:a.sources.triase.enabled,everyMin:String(a.sources.triase.everyMin)}}}},me=(a,s)=>{const t=s.launchGuard??fe.launchGuard,r=s.sources.backlog,k=s.sources.triase;return{...s,maxConcurrent:H(a.maxConcurrent,1,1/0,s.maxConcurrent),autonomy:a.autonomy,launchGuard:{...t,enabled:a.guardOn,maxLoadPerCore:H(a.maxLoad,.1,1/0,t.maxLoadPerCore,!1),minMemAvailablePct:H(a.minMem,0,100,t.minMemAvailablePct,!1)},sources:{...s.sources,backlog:{...r,enabled:a.sources.backlog.enabled,everyMin:H(a.sources.backlog.everyMin,1,1/0,r.everyMin)},triase:{...k,enabled:a.sources.triase.enabled,everyMin:H(a.sources.triase.everyMin,1,1/0,k.everyMin)}}}},Sa=a=>`${a.lastRunAt?`terakhir ${ye(a.lastRunAt)}`:"belum pernah dicek"} · ${a.nextRunAt?`berikutnya ${ta(a.nextRunAt)}`:"belum dijadwalkan"}`;function Ca({cfg:a,sources:s,admission:t,onWrite:r,busy:k}){const{draft:m,setDraft:b,dirty:d}=sa(se(a)),g=l=>se(me(l,a)),j=()=>b(l=>g(l)),v=()=>{const l=me(m,a);b(se(l)),r(l)},w=l=>{l.key==="Enter"&&(l.preventDefault(),v())},u=(l,c)=>b(x=>({...x,sources:{...x.sources,[l]:{...x.sources[l],...c}}}));return e.jsxs("div",{className:"hn-sched-panel",children:[e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-sesi",children:[e.jsx("h3",{id:"sched-set-sesi",className:"hn-sched-group-title",children:"Sesi"}),e.jsxs("div",{className:"hn-sched-grid",children:[e.jsx(P,{label:"Batas sesi bersamaan",hint:"Termasuk terminal dan shell yang kamu buka sendiri.",children:e.jsx(M,{type:"number",min:1,value:m.maxConcurrent,"aria-label":"Batas sesi bersamaan",placeholder:"mis. 6",onChange:l=>b(c=>({...c,maxConcurrent:l.target.value})),onBlur:j,onKeyDown:w})}),e.jsx(P,{label:"Saat ada keputusan yang belum jelas",hint:"Keputusan yang ambigu tetap ditanyakan ke lead atau kamu.",children:e.jsx(O,{value:m.autonomy,"aria-label":"Mode otonomi",onChange:l=>b(c=>({...c,autonomy:l.target.value})),options:pa})})]})]}),e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-peluncuran",children:[e.jsx("h3",{id:"sched-set-peluncuran",className:"hn-sched-group-title",children:"Peluncuran"}),e.jsx(te,{label:"Tahan peluncuran saat server sibuk",checked:m.guardOn,onChange:l=>b(c=>({...c,guardOn:l}))}),e.jsx("p",{className:"hn-sched-group-hint",children:"Mencegah sesi baru diluncurkan saat batas sesi penuh, beban CPU per inti terlalu tinggi, atau memori bebas terlalu sedikit. Berlaku juga untuk peluncuran manual. Mematikannya melewati ketiga pemeriksaan itu. Terpisah dari saklar scheduler dan sumber."}),e.jsxs("div",{className:"hn-sched-grid",children:[e.jsx(P,{label:"Batas beban CPU per inti",hint:"Di atas angka ini, sesi baru tidak diluncurkan.",children:e.jsx(M,{type:"number",min:.1,step:"any",value:m.maxLoad,"aria-label":"Batas beban CPU per inti",placeholder:"mis. 2.5",onChange:l=>b(c=>({...c,maxLoad:l.target.value})),onBlur:j,onKeyDown:w})}),e.jsx(P,{label:"Memori bebas minimal (%)",hint:"Di bawah angka ini, sesi baru tidak diluncurkan.",children:e.jsx(M,{type:"number",min:0,max:100,step:"any",value:m.minMem,"aria-label":"Memori bebas minimal (%)",placeholder:"mis. 15",onChange:l=>b(c=>({...c,minMem:l.target.value})),onBlur:j,onKeyDown:w})})]}),t&&e.jsx(wa,{status:t})]}),e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-sumber",children:[e.jsx("h3",{id:"sched-set-sumber",className:"hn-sched-group-title",children:"Sumber otomatis"}),["backlog","triase"].map(l=>{const c=s.find(x=>x.id===l);return e.jsxs("div",{className:"hn-sched-source",children:[e.jsx(te,{label:J[l],checked:m.sources[l].enabled,onChange:x=>u(l,{enabled:x})}),e.jsx("span",{className:"hn-sched-spacer"}),e.jsxs("label",{className:"hn-sched-inline-field",children:["cek tiap",e.jsx(M,{type:"number",min:1,"aria-label":`Interval cek ${J[l]}`,placeholder:"mis. 30",value:m.sources[l].everyMin,onChange:x=>u(l,{everyMin:x.target.value}),onBlur:j,onKeyDown:w}),"menit"]}),c&&e.jsx("span",{className:"hn-sched-source-facts",children:Sa(c)})]},l)})]}),e.jsxs("div",{className:"hn-sched-savebar",children:[d&&e.jsx("span",{role:"status",className:"hn-sched-note",children:"Ada perubahan yang belum disimpan."}),e.jsx(C,{leftIcon:"save",disabled:k,onClick:v,children:"Simpan setelan"})]})]})}function Na({projects:a,onToggle:s,busyId:t}){return e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-project",children:[e.jsx("h3",{id:"sched-set-project",className:"hn-sched-group-title",children:"Project yang diizinkan"}),e.jsx("p",{className:"hn-sched-group-hint",children:"Scheduler hanya menyentuh project yang diizinkan. Default: tidak diizinkan."}),a.length===0?e.jsx("p",{className:"hn-sched-empty",children:"Belum ada project."}):e.jsx(Z,{label:"Project yang diizinkan",children:a.map(r=>e.jsx(D,{actions:r.schedulerOptIn?e.jsx(C,{size:"sm",variant:"ghost",leftIcon:"ban",disabled:t===r.id,onClick:()=>s(r.id,!1),children:"Cabut izin"}):e.jsx(C,{size:"sm",leftIcon:"check",disabled:t===r.id,onClick:()=>s(r.id,!0),children:"Izinkan"}),children:e.jsx("span",{className:"hn-sched-row-text",children:e.jsxs("span",{className:"hn-sched-row-head",children:[e.jsx("span",{className:"hn-sched-row-title",children:r.name}),e.jsx(Q,{tone:r.schedulerOptIn?"ok":"neutral",size:"sm",children:r.schedulerOptIn?"diizinkan":"tidak diizinkan"})]})})},r.id))})]})}function Ia(a){const[s,t]=o.useState(null),[r,k]=o.useState(null),m=o.useCallback(()=>{I.getSettings().then(d=>{t(d),k(null)}).catch(d=>k(L("memuat orkestrasi",d)))},[]);o.useEffect(()=>{m()},[m]);const b=o.useCallback(async(d,g)=>{if(!s)return;const j=s;t({...j,orchestration:d});try{const v=await I.getSettings().catch(()=>{});await I.putSettings(ra(j,{...j,orchestration:d},v)),a(g,"ok","check-circle-2")}catch(v){t(j),a(L("menyimpan orkestrasi",v),"err","alert-triangle")}},[s,a]);return{setting:s,error:r,load:m,writeOrchestration:b}}function Pa({snap:a}){return e.jsxs("section",{className:"hn-sched-group","aria-labelledby":"sched-set-orkestrasi",children:[e.jsx("h3",{id:"sched-set-orkestrasi",className:"hn-sched-group-title",children:"Orkestrasi subagen per fase"}),e.jsx("p",{className:"hn-sched-group-hint",children:"Perubahan tersimpan saat diubah. Buka satu flow untuk mengatur model dan effort per fase."}),a.error?e.jsx(V,{message:a.error,onRetry:a.load}):a.setting?e.jsx(la,{variant:"accordion",orchestration:a.setting.orchestration,onChange:(s,t)=>void a.writeOrchestration(s,t)}):e.jsx(G,{rows:2,label:"Memuat orkestrasi…"})]})}function $a({projects:a,backlog:s,onProjectChanged:t,onToast:r,onGotoTerminal:k}){const{confirm:m,dialog:b}=pe(),[d,g]=o.useState(null),[j,v]=o.useState("loading"),[w,u]=o.useState(!1),[l,c]=o.useState(null),[x,E]=T("scheduler","tab","antre",ge(...ua)),N=Ia(r),i=o.useCallback((h=!1)=>{h||v("loading"),I.getSchedulerState().then(f=>{g(f),v("ready")}).catch(()=>{h||v("error")})},[]);o.useEffect(()=>{i()},[i]),ve({topic:"schedulerState",params:{},apply:h=>{g(h.state),v("ready")},refetch:()=>i(!0),pollMs:we});const S=o.useCallback(async(h,f="Setelan scheduler tersimpan")=>{u(!0);try{await I.putSchedulerConfig(h),r(f,"ok","save"),i(!0)}catch(y){r(he(y)??L("menyimpan setelan",y),"err","x-circle")}finally{u(!1)}},[i,r]),X=o.useCallback((h,f)=>{const y=f==="jeda";m({title:y?"Jeda scheduler?":"Hentikan scheduler?",eyebrow:"scheduler · rem darurat",message:y?"Scheduler berhenti meluncurkan sesi baru dari antrean sampai kamu melanjutkannya. Sesi yang sudah berjalan tidak dihentikan.":void 0,impact:y?void 0:["Sumber backlog dan triase tidak lagi diperiksa sampai diaktifkan lagi.","Antrean tetap tersimpan dan tidak diproses selama berhenti.","Sesi yang sudah berjalan tetap berjalan."],confirmLabel:y?"Jeda scheduler":"Hentikan scheduler",icon:y?"pause":"square",tone:y?"default":"danger",run:()=>S(h,y?"Scheduler dijeda":"Scheduler dihentikan")})},[m,S]),Y=o.useCallback(async(h,f)=>{c(h);try{await I.updateProject(h,{schedulerOptIn:f}),await t(h),r(f?"Project diizinkan untuk scheduler":"Izin scheduler dicabut","ok")}catch(y){r(L("mengubah izin project",y),"err","x-circle")}finally{c(null)}},[t,r]),F=o.useCallback(async(h,f)=>{c(h);try{f==="cancel"?(await I.cancelSchedulerQueueItem(h),r("Item antrean dibatalkan","ok","ban")):(await I.requeueSchedulerQueueItem(h),r("Item dikembalikan ke antrean","ok","rotate-ccw"))}catch(y){const U=f==="cancel"?"membatalkan item antrean":"mengembalikan item ke antrean";r(he(y)??L(U,y),"err","x-circle")}finally{c(null),i(!0)}},[i,r]);if(j==="loading")return e.jsx(G,{rows:4,label:"Memuat scheduler…"});if(j==="error"||!d)return e.jsx(Qe,{kind:"error",hint:"Gagal memuat state scheduler.",action:()=>i(),actionLabel:"Coba lagi"});const R={backlog:s,projectName:h=>{var f;return((f=a.find(y=>y.id===h))==null?void 0:f.name)??"Project lain"}},A=d.queueCounts,z=(A.done??0)+(A.failed??0)+(A.canceled??0),B=[{value:"antre",label:"Antre",count:A.queued||void 0},{value:"berjalan",label:"Berjalan",count:d.sessions.length||void 0},{value:"riwayat",label:"Riwayat",count:z||void 0},{value:"cron",label:"Cron"},{value:"setelan",label:"Setelan"}];return e.jsxs("div",{className:"hn-sched",children:[e.jsx(ya,{cfg:d.config,cap:d.cap,liveCount:d.liveCount,onWrite:S,onAsk:X,busy:w}),e.jsxs(be,{tabs:B,value:x,onChange:h=>E(h),children:[e.jsx($,{value:"antre",className:"hn-sched-panel",children:e.jsx(Se,{what:"antrean",status:"queued",count:A.queued,empty:"Antrean kosong.",render:h=>e.jsx(ja,{q:h,ctx:R,busy:l===h.id,onCancel:f=>void F(f,"cancel")},h.id)})}),e.jsx($,{value:"berjalan",className:"hn-sched-panel",children:d.sessions.length===0?e.jsx("p",{className:"hn-sched-empty",children:"Tidak ada sesi dari scheduler yang sedang berjalan."}):e.jsx(Z,{label:"Sesi berjalan",children:d.sessions.map(h=>e.jsx(xa,{s:h,ctx:R,onGotoTerminal:k},h.id))})}),e.jsx($,{value:"riwayat",className:"hn-sched-panel",children:x==="riwayat"&&e.jsx(fa,{counts:A,ctx:R,busyId:l,onRowAction:F,onToast:r})}),e.jsx($,{value:"cron",className:"hn-sched-panel",children:x==="cron"&&e.jsx(oa,{projects:a,onProjectChanged:t,onToast:r,timeZone:d.serverTimeZone})}),e.jsxs($,{value:"setelan",className:"hn-sched-panel",children:[e.jsx(Ca,{cfg:d.config,sources:d.sources,admission:d.admission,onWrite:h=>void S(h),busy:w}),e.jsx(Na,{projects:a,onToggle:Y,busyId:l}),e.jsx(Pa,{snap:N})]})]}),b]})}export{$a as SchedulerScreen};