hanoman 0.9.37 → 0.9.38

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.
Files changed (26) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/cli.js +77 -9
  3. package/dist/server.js +669 -395
  4. package/docs/agent-integration.md +5 -2
  5. package/package.json +1 -1
  6. package/web/assets/{DalangHanomanScreen-JE8gkztH.js → DalangHanomanScreen-wpAO0xvb.js} +1 -1
  7. package/web/assets/{DocPreviewModal-B23vI_It.js → DocPreviewModal-CbhkDUJ2.js} +1 -1
  8. package/web/assets/{DocsWorkspace-CbV27H6A.js → DocsWorkspace-CcB0LGFV.js} +1 -1
  9. package/web/assets/{IdeScreen-BY7sm97W.js → IdeScreen-DI4v3ZkU.js} +1 -1
  10. package/web/assets/{LeadScreen-BFwI29zS.js → LeadScreen-BdS_xX_f.js} +1 -1
  11. package/web/assets/{ReviewScreen-pM6zzGZl.js → ReviewScreen-Ddw5U2sM.js} +1 -1
  12. package/web/assets/{SchedulerScreen-BIhqn3X1.js → SchedulerScreen-D6LGVrhM.js} +1 -1
  13. package/web/assets/{SettingsScreen-C_TW3mbs.js → SettingsScreen-CFNcg1T8.js} +1 -1
  14. package/web/assets/{TeamScreen-RT926lDf.js → TeamScreen-BkxPDI5P.js} +1 -1
  15. package/web/assets/TerminalScreen-CEQFK9Rc.js +2 -0
  16. package/web/assets/{TriageScreen-Zp1bdRnl.js → TriageScreen-B-HdZsEt.js} +1 -1
  17. package/web/assets/{VpsScreen-Jnb8C1o2.js → VpsScreen-CWp29NL_.js} +2 -2
  18. package/web/assets/{fields-B_3dIGcG.js → fields-BY7SYerd.js} +1 -1
  19. package/web/assets/{index-C3KwOJxI.css → index-B4b6i2tH.css} +1 -1
  20. package/web/assets/index-C4Py9MJV.js +1032 -0
  21. package/web/assets/{live-CNp86nGW.js → live-CBa_7-hn.js} +1 -1
  22. package/web/assets/{sched-lead-shared-BUcJMfNH.js → sched-lead-shared-CQIoYIzG.js} +1 -1
  23. package/web/assets/{settings-rebase-CYr7W_rB.js → settings-rebase-C3611gs8.js} +1 -1
  24. package/web/index.html +2 -2
  25. package/web/assets/TerminalScreen-fpC5a2jS.js +0 -2
  26. package/web/assets/index-CbX7iwxN.js +0 -1012
@@ -1,4 +1,4 @@
1
- import{br as ea,bs as aa,bt as na,bu as ta,bv as ia,bw as sa,bx as la,by as ra,bz as da,bA as ca,bB as oa,bC as ua,bD as ha,bE as ma,bF as ga,bG as ka,bH as pa,bI as ba,bJ as ja,bK as fa,bL as xa,bM as va,bN as ya,h as y,i as K,j as e,f as V,bO as wa,bP as Sa,a7 as Ce,bQ as Na,a6 as de,af as Ca,bR as Ea,a8 as Ee,aJ as M,b2 as J,g as T,B as x,bS as Pe,bg as Aa,aY as be,a9 as Oa,aa as Pa,ab as Ma,bT as Ia,bU as Da,bV as _a,bW as Me,bX as Ie,n as X,H as La,bY as ae,bZ as se,b_ as Ba,b$ as we,d as ie,I as le,m as W,C as te,e as Z,ac as oe,c0 as Ha,c1 as Ge,c2 as ge,c3 as Ue,c4 as Ra,c5 as ue,c6 as Ae,c7 as za,c8 as De,c9 as Fa,ca as $a,cb as Ka,cc as pe,$ as Ga,b as Te,cd as Ua,ce as Ta,cf as Wa,ai as Se,q as Ja,D as Va,cg as qa,ch as Ya}from"./index-CbX7iwxN.js";import{R as c}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import{S as Oe,s as We,u as $,c as Je,a as E,b as _e,P as G,d as je,e as ne,A as Qa,f as Ve,g as qe,C as Xa,h as Za,F as ke,E as Ne,N as fe,B as he,i as en,n as Le,j as an,r as nn,D as tn}from"./fields-B_3dIGcG.js";import{r as Ye,O as sn}from"./settings-rebase-CYr7W_rB.js";import{D as ln}from"./DocPreviewModal-B23vI_It.js";import"./xterm-3VOAfa_q.js";/* empty css */const rn=[...ea,...aa,...na,...ta,...ia,...sa,...la,...ra,...da,...ca,...oa,...ua,...ha,...ma,...ga,...ka,...pa,...ba,...ja,...fa,...xa,...va,...ya],dn=2,Be=()=>{};function cn(a){const[t,i]=c.useState(null),[r,d]=c.useState(!1),h=c.useRef(null),l=c.useRef(a);l.current=a;const s=c.useRef(Promise.resolve()),m=c.useCallback(g=>{h.current=g,i(g)},[]),j=c.useCallback(()=>{d(!1),m(null),y.getSettings().then(g=>m(g),()=>d(!0))},[m]);c.useEffect(()=>{j()},[j]);const p=c.useCallback((g,S,P,w)=>{const D=h.current;if(!D)return Promise.resolve(!1);const O=Object.keys(g).filter(I=>JSON.stringify(g[I])!==JSON.stringify(D[I]));m(g);const N=s.current.then(async()=>{const I=await y.getSettings().catch(()=>{});await y.putSettings(Ye(D,g,I))});return s.current=N.then(Be,Be),N.then(()=>{var I;return S&&((I=l.current)==null||I.call(l,S,P||"ok",w||"check-circle-2")),!0},I=>{var C;const z=Object.fromEntries(O.map(H=>[H,D[H]]));return m({...h.current??D,...z}),(C=l.current)==null||C.call(l,K("menyimpan pengaturan",I),"err","alert-triangle"),!1})},[m]),b=c.useCallback((g,S)=>{const P=h.current;return P?p({...P,...g},S):Promise.resolve(!1)},[p]),k=c.useCallback(g=>{const S=h.current;S&&m(g(S))},[m]),f=c.useCallback(()=>h.current,[]);return{s:t,failed:r,load:j,persist:p,save:b,update:k,current:f}}function on(a){const t=a.trim().toLowerCase();return t?Oe.flatMap(i=>i.sections).filter(i=>`${i.label} ${i.keywords}`.toLowerCase().includes(t)).map(i=>({key:i.key,path:We(i.key)})):[]}const xe=(a,t)=>(a??"").toLowerCase().includes(t);function un(a,t){if(!a)return 0;const i=t.trim().toLowerCase(),r=Array.from(a.querySelectorAll("[data-setting-row]")),d=Array.from(a.querySelectorAll("[data-setting-card]")),h=s=>{var m;return((m=s.parentElement)==null?void 0:m.closest("[data-setting-card]"))??null};let l=0;return i?(d.forEach(s=>{const m=xe(s.getAttribute("data-search"),i),j=Array.from(s.querySelectorAll("[data-setting-row]")).filter(b=>h(b)===s);if(j.length===0){s.hidden=!m,m&&l++;return}let p=!1;j.forEach(b=>{const k=m||xe(b.getAttribute("data-search"),i);b.hidden=!k,k&&(p=!0,l++)}),s.hidden=!(m||p)}),r.forEach(s=>{if(h(s))return;const m=xe(s.getAttribute("data-search"),i);s.hidden=!m,m&&l++}),l):(r.forEach(s=>{s.hidden=!1}),d.forEach(s=>{s.hidden=!1}),r.length+d.filter(s=>!s.querySelector("[data-setting-row]")).length)}function hn(a,t,i){const[r,d]=c.useState(0);return c.useLayoutEffect(()=>{const h=a.current,l=()=>d(un(h,t));if(l(),!h||typeof MutationObserver>"u")return;const s=new MutationObserver(l);return s.observe(h,{childList:!0,subtree:!0}),()=>s.disconnect()},[t,i,a]),r}function mn({value:a,onChange:t,hits:i,onPick:r}){return e.jsxs("div",{className:"hn-set-search",role:"search",children:[e.jsx(V,{type:"search","aria-label":"Cari pengaturan",placeholder:"mis. notifikasi, telegram, token",value:a,leftIcon:"search",className:"hn-set-full",onChange:d=>t(d.target.value),onKeyDown:d=>{d.key==="Escape"&&a&&t("")}}),a.trim()!==""&&i.length>0&&e.jsx("ul",{className:"hn-set-search-hits","aria-label":"Bagian yang cocok",children:i.map(d=>e.jsx("li",{children:e.jsx("button",{type:"button",className:"hn-set-search-hit",onClick:()=>r(d.key),children:d.path})},d.key))})]})}const gn={default:null,tampil:!0,sembunyi:!1};function re(a,t,i,r){return $({value:i,delayMs:0,save:d=>a.save({[t]:d},r+(d?" · aktif":" · nonaktif"))})}function kn({s:a,store:t,onToast:i,codexVer:r}){const d=wa(),[h,l]=c.useState(null),[s,m]=c.useState("");c.useEffect(()=>{y.getMethodStatus().then(l).catch(()=>l(null)),y.listProjects({limit:100}).then(n=>m(v=>{var F;return v||(((F=n.items.find(ce=>ce.binding??ce.repoDir))==null?void 0:F.id)??"")})).catch(n=>i==null?void 0:i(K("memuat daftar project",n),"err","alert-triangle"))},[]);const[j,p]=Sa(),b=j===null?"default":j?"tampil":"sembunyi",k=re(t,"notifyDone",a.notifyDone,"Notifikasi backlog selesai"),f=$({value:a.notifySound,delayMs:0,save:n=>t.save({notifySound:n},"Sound → "+n)}),g=re(t,"notifyDecision",a.notifyDecision,"Notifikasi keputusan"),S=re(t,"notifyDecisionTelegram",a.notifyDecisionTelegram,"Keputusan ke Telegram"),P=$({value:a.notifyDecisionSound,delayMs:0,save:n=>t.save({notifyDecisionSound:n},"Sound keputusan → "+n)}),w=re(t,"notifyFail",a.notifyFail,"Notifikasi gagal"),D=re(t,"autoDefault",a.autoDefault,"Full-auto default"),O=re(t,"autoScaffold",a.autoScaffold,"Auto-scaffold"),N=a.agent??"claude",I=a.codex??Ce,z=$({value:N,delayMs:0,save:n=>t.save({agent:n},"Agen → "+n)}),C=$({value:a.model,delayMs:0,save:n=>t.save({model:n,...Je(n,a.effort)},"Model claude → "+n)}),H=$({value:a.effort,delayMs:0,save:n=>t.save({effort:n},"Effort claude → "+n)}),L=$({value:I.model,delayMs:0,save:n=>t.save({codex:{model:n,effort:Na(n,I.effort)}},"Model codex → "+n)}),Q=$({value:I.effort,delayMs:0,save:n=>t.save({codex:{...I,effort:n}},"Effort codex → "+n)}),q=a.antigravity??de,Y=$({value:q.model,delayMs:0,save:n=>t.save({antigravity:{model:n,effort:Ca("antigravity",n,q.effort)}},"Model Antigravity → "+n)}),U=$({value:q.effort,delayMs:0,save:n=>t.save({antigravity:{...q,effort:n}},"Effort Antigravity → "+n)}),o=$({value:a.goal.enabled,delayMs:0,save:n=>t.save({goal:{...a.goal,enabled:n}},"Mode goal"+(n?" · aktif":" · nonaktif"))}),A=$({value:a.goal.condition,save:n=>t.save({goal:{...a.goal,condition:n}},"Kondisi mode goal disimpan")}),B=$({value:a.verifyScope??"changed",delayMs:0,save:n=>t.save({verifyScope:n},"Scope verifikasi → "+n)}),u=$({value:Ea(a.method).id,delayMs:0,save:n=>t.save({method:n},"Metode → "+n)}),_=async n=>{if(s)try{await y.createShell(s,{method:n.method,agent:n.agent}),i==null||i(`Pemasangan ${n.label} · ${ne[n.agent]} berjalan di Terminal`,"ok","terminal")}catch{i==null||i("Gagal membuka sesi terminal pemasangan","err","alert-triangle")}},R={agent:N,...Ee({claude:{model:a.model,effort:a.effort},codex:I,antigravity:a.antigravity??de},N)};return e.jsxs(e.Fragment,{children:[e.jsxs(M,{eyebrow:"sesi",title:"Sesi & notifikasi","data-setting-card":!0,"data-search":"sesi notifikasi suara telegram keputusan",children:[e.jsx(E,{title:"Notifikasi backlog selesai",desc:"Toast + sound saat sebuah backlog mencapai stage done. Daftar lonceng tetap terisi meski dimatikan.",save:k,children:e.jsx(J,{"aria-label":"Notifikasi backlog selesai",checked:k.value,onChange:n=>k.set(n)})}),e.jsx(E,{title:"Sound notifikasi",desc:"Durasi nada saat backlog selesai.",save:f,children:e.jsxs("div",{className:"hn-set-inline",children:[e.jsx(T,{size:"sm","aria-label":"Sound notifikasi",value:f.value,options:_e,className:"hn-set-w-sm",onChange:n=>f.set(n.target.value)}),e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"volume-2",disabled:f.value==="off",onClick:()=>Pe(f.value),children:"Preview"})]})}),e.jsx(E,{title:"Notifikasi butuh keputusan",desc:"Toast + sound saat sesi Claude berhenti menunggu keputusanmu. Nada sengaja beda dari selesai.",save:g,children:e.jsx(J,{"aria-label":"Notifikasi keputusan",checked:g.value,onChange:n=>g.set(n)})}),e.jsx(E,{title:"Kirim keputusan ke Telegram",desc:"Pesan ke user id di allowlist Telegram saat sesi menunggu keputusanmu, supaya tak menunggu sampai dashboard dibuka. Perlu bot token + allowlist; gateway percakapan tak perlu berjalan.",save:S,children:e.jsx(J,{"aria-label":"Kirim keputusan ke Telegram",checked:S.value,onChange:n=>S.set(n)})}),e.jsx(E,{title:"Sound keputusan",desc:"Nada saat sebuah sesi menunggu keputusan.",save:P,children:e.jsxs("div",{className:"hn-set-inline",children:[e.jsx(T,{size:"sm","aria-label":"Sound keputusan",value:P.value,options:_e,className:"hn-set-w-sm",onChange:n=>P.set(n.target.value)}),e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"volume-2",disabled:P.value==="off",onClick:()=>Pe(P.value),children:"Preview"})]})}),e.jsx(E,{title:"Notifikasi saat sesi gagal",last:!0,desc:"Kirim notifikasi ketika sesi Claude Code berakhir dengan error.",save:w,children:e.jsx(J,{"aria-label":"Notifikasi gagal",checked:w.value,onChange:n=>w.set(n)})})]}),e.jsxs(M,{eyebrow:"umum",title:"Perilaku sesi","data-setting-card":!0,"data-search":"perilaku sesi full-auto scaffold doc index",children:[e.jsx(E,{title:"Full-auto sebagai default",desc:"Run baru jalan sendiri sampai selesai. Manusia tetap bisa steer / interupsi kapan pun.",save:D,children:e.jsx(J,{"aria-label":"Full-auto sebagai default",checked:D.value,onChange:n=>D.set(n)})}),e.jsx(E,{title:"Auto-scaffold doc index",desc:"Project yang dibuat dari nol otomatis disiapkan indeks dokumennya setelah tujuannya terkunci.",save:O,children:e.jsx(J,{"aria-label":"Auto-scaffold",checked:O.value,onChange:n=>O.set(n)})}),e.jsx(E,{title:"Tampilkan Hanoman (pet)",last:!0,search:"pet hanoman maskot tampil sembunyi",desc:"Pendamping kecil di sudut layar. Pilihan ini hanya berlaku di browser ini. Default: aktif di desktop, mati di tablet & ponsel.",children:e.jsxs(Aa,{"aria-label":"Tampilkan Hanoman (pet)",direction:"row",value:b,onChange:n=>p(gn[n]??null),children:[e.jsx(be,{value:"default",label:"Default"}),e.jsx(be,{value:"tampil",label:"Tampilkan"}),e.jsx(be,{value:"sembunyi",label:"Sembunyikan"})]})})]}),e.jsxs(M,{eyebrow:"model",title:"Agen & model — default global","data-setting-card":!0,"data-search":"agen model default effort claude codex agen sesi baru",children:[e.jsxs(G,{children:["Default untuk sesi baru; bisa di-override per sesi saat ",e.jsx("b",{children:"Start"}),". Di terminal, ",e.jsx("code",{children:"/model"})," ","mengubahnya kapan saja. Dengan orkestrasi aktif, model ini menjadi model ",e.jsx("b",{children:"orchestrator"}),"; model & effort tiap fase diatur di bagian ",e.jsx("b",{children:"Orkestrasi"})," pada Agen & model. Yang benar-benar dipakai adalah blok milik agen terpilih di bawah — blok runtime lain tersimpan, menunggu giliran."]}),e.jsx(E,{title:"Agen default",desc:"Sesi backlog masih bisa memilih agen lain saat Start.",save:z,children:e.jsx(T,{size:"sm","aria-label":"Agen default",value:z.value,className:"hn-set-w-sm",options:Oa,onChange:n=>z.set(n.target.value)})}),e.jsxs("div",{"data-testid":"agent-group-antigravity",className:"hn-set-group",children:[e.jsx(je,{id:"antigravity",label:ne.antigravity,active:N==="antigravity"}),e.jsx(Qa,{}),e.jsx(E,{title:"Model",desc:"Model parent diteruskan ke agy --model.",save:Y,children:e.jsx(T,{size:"sm","aria-label":"Model antigravity",value:Y.value,options:Pa("antigravity",Y.value),onChange:n=>Y.set(n.target.value)})}),e.jsx(E,{title:"Effort",last:!0,desc:"Effort mengikuti kemampuan slug model parent.",save:U,children:e.jsx(T,{size:"sm","aria-label":"Effort antigravity",value:U.value,options:Ma("antigravity",Y.value).map(n=>({value:n,label:n})),onChange:n=>U.set(n.target.value)})})]}),e.jsxs("div",{"data-testid":"agent-group-claude",className:"hn-set-group",children:[e.jsxs("div",{className:"hn-set-catalog",children:["Katalog model diperiksa otomatis setiap 5 menit.",Object.entries(d.providers).map(([n,v])=>e.jsxs("div",{children:[n,": ",v.source==="bundled"?"daftar bawaan":v.source==="cache"?"cache terakhir":"dari CLI",v.checkedAt?" · diperiksa "+new Date(v.checkedAt).toLocaleTimeString():"",v.error?" · "+v.error:""]},n))]}),e.jsx(je,{id:"claude",label:ne.claude,active:N==="claude"}),e.jsx(E,{title:"Model",desc:"Diteruskan apa adanya ke `claude --model`.",save:C,children:e.jsx(T,{size:"sm","aria-label":"Model claude",value:C.value,options:Ve(C.value),className:"hn-set-w-sm",onChange:n=>C.set(n.target.value)})}),e.jsx(E,{title:"Effort",last:!0,desc:"Anggaran berpikir per giliran (`claude --effort`).",save:H,children:e.jsx(T,{size:"sm","aria-label":"Effort claude",value:H.value,options:qe(C.value),className:"hn-set-w-xs",onChange:n=>H.set(n.target.value)})})]}),e.jsxs("div",{"data-testid":"agent-group-codex",className:"hn-set-group hn-set-group--codex",children:[e.jsx(je,{id:"codex",label:ne.codex,active:N==="codex"}),e.jsx(Xa,{model:L.value,codexVer:r}),e.jsx(E,{title:"Model",desc:"Diteruskan apa adanya ke `codex -m`.",save:L,children:e.jsx(T,{size:"sm","aria-label":"Model codex",value:L.value,className:"hn-set-w-sm",options:Ia(Da,L.value),onChange:n=>L.set(n.target.value)})}),e.jsx(E,{title:"Effort",last:!0,desc:"Diteruskan ke `codex -c model_reasoning_effort`.",save:Q,children:e.jsx(T,{size:"sm","aria-label":"Effort codex",value:Q.value,className:"hn-set-w-xs",options:_a(L.value).map(n=>({value:n,label:n})),onChange:n=>Q.set(n.target.value)})})]}),e.jsxs("div",{className:"hn-set-inherited-note","data-testid":"session-default-summary",children:["Sesi baru memakai ",e.jsx("b",{children:ne[R.agent]})," · ",e.jsx("code",{children:R.model})," · ",e.jsx("code",{children:R.effort}),"."]})]}),e.jsxs(M,{eyebrow:"goal",title:"Mode goal — sesi backlog","data-setting-card":!0,"data-search":"mode goal kondisi template gate stop",children:[N==="antigravity"&&e.jsx(G,{children:"Mode goal native Antigravity belum didukung. Nilai global tetap disimpan; matikan mode goal secara eksplisit atau pilih runtime lain sebelum memulai sesi."}),e.jsxs(G,{children:["Sesi backlog lahir dengan gate ",e.jsx("code",{children:"Stop"}),": ia menolak berhenti sampai kondisinya terbukti di transkrip. Interupsi manusia (",e.jsx("code",{children:"Esc"}),") tetap bekerja; melepas gate sepenuhnya = hentikan sesinya. Sesi scheduler mengikuti setelan ini."]}),e.jsx(E,{title:"Aktif sebagai default",desc:"Sesi backlog baru lahir dengan mode goal. Masih bisa dimatikan per sesi saat Start.",save:o,children:e.jsx(J,{"aria-label":"Mode goal default",disabled:N==="antigravity"&&!o.value,checked:o.value,onChange:n=>o.set(n)})}),e.jsx(E,{title:"Kondisi (template global)",last:!0,desc:"Kosong = kondisi bawaan hanoman: semua fase tercatat di phase file, plan tak menyisakan task, push sukses.",save:A,children:e.jsx("div",{className:"hn-set-w-field",children:e.jsx(pn,{value:A.value,onSet:A.set,onFlush:A.flush})})})]}),e.jsxs(M,{eyebrow:"verifikasi",title:"Scope verifikasi — sesi backlog","data-setting-card":!0,"data-search":"scope verifikasi hanya yang berubah seluruh project uji jangan jalankan test",children:[e.jsxs(G,{children:["Beberapa sesi berjalan bersamaan di perangkat ini. ",e.jsx("b",{children:"Hanya yang berubah"})," menyuruh sesi menguji hanya berkas yang ia ubah — misalnya dengan ",e.jsx("code",{children:"vitest --changed"})," (uji) dan typecheck per paket — alih-alih seluruh project. Dengan begitu RAM dan CPU tetap tersisa untuk sesi lain. Uji penuh, lint penuh, dan build penuh tetap dijalankan manusia sebelum merge. Bila perangkat tak kuat menjalankan test sama sekali, pilih ",e.jsx("b",{children:"Jangan jalankan test"}),": sesi tetap menulis test, tapi memverifikasi dengan membaca kode dan menyerahkan run test ke manusia."]}),e.jsx(E,{title:"Scope default",last:!0,desc:"Sesi backlog baru lahir dengan scope ini. Masih bisa diubah per sesi saat Start.",save:B,children:e.jsx(T,{size:"sm","aria-label":"Scope verifikasi default",value:B.value,className:"hn-set-w-md",options:[{value:"changed",label:"Hanya yang berubah"},{value:"full",label:"Seluruh project"},{value:"none",label:"Jangan jalankan test"}],onChange:n=>B.set(n.target.value)})})]}),e.jsxs(M,{eyebrow:"metode",title:"Metode workflow — sesi backlog","data-setting-card":!0,"data-search":"metode workflow skill direktori plan spec pemasangan",children:[e.jsxs(G,{children:["Metode menentukan ",e.jsx("b",{children:"skill mana yang dimuat di tiap fase"})," dan ",e.jsx("b",{children:"di direktori mana plan & spec ditulis"}),". Fase-fasenya sendiri tak berubah. Gerbang plan memindai direktori SEMUA metode, jadi item yang berpindah metode tak pernah lolos lewat direktori kosong."]}),e.jsx(E,{title:"Metode default",last:!0,desc:"Sesi backlog baru lahir dengan metode ini. Masih bisa diubah per sesi saat Start.",save:u,children:e.jsx(T,{size:"sm","aria-label":"Metode default",className:"hn-set-w-md",value:u.value,options:Me.map(n=>({value:n,label:Ie[n].label})),onChange:n=>u.set(n.target.value)})}),h&&e.jsxs("div",{"data-testid":"method-status",className:"hn-set-method-status",children:[Me.map(n=>e.jsxs("div",{className:"hn-set-method",children:[e.jsx("div",{className:"hn-set-method-name",children:Ie[n].label}),h.methods.filter(v=>v.method===n).map(v=>e.jsxs("div",{"data-testid":`method-status-${v.method}-${v.agent}`,className:"hn-set-method-row",children:[e.jsx(X,{tone:v.ready?"ok":"warn",children:v.ready?"siap":"belum siap"}),e.jsxs("div",{className:"hn-set-method-text",children:[e.jsx("b",{children:ne[v.agent]}),v.availabilityReason&&e.jsx("div",{children:v.availabilityReason}),!v.ready&&e.jsxs("div",{className:"hn-set-method-missing",children:[v.missingPackages.length>0&&e.jsxs("div",{children:["paket kurang: ",e.jsx("code",{children:v.missingPackages.join(" · ")})]}),v.missingSkills.length>0&&e.jsxs("div",{children:["skill kurang: ",e.jsx("code",{children:v.missingSkills.join(" · ")})]})]})]}),!v.ready&&e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"download",disabled:!s||v.available===!1,onClick:()=>_(v),children:"Pasang"})]},v.agent))]},n)),e.jsx(Za,{children:s?e.jsxs(e.Fragment,{children:["Pemasangan berjalan di ",e.jsx("b",{children:"sesi terminal"})," project ",e.jsx("code",{children:s})," — outputnya bisa ditonton di Terminal. hanoman sendiri tak pernah memasang apa pun."]}):e.jsx(e.Fragment,{children:"Pemasangan butuh satu project yang sudah di-bind ke checkout lokal: perintahnya dijalankan di sesi terminal project itu."})})]})]})]})}function pn({value:a,onSet:t,onFlush:i}){return e.jsx("div",{onBlur:()=>i(),children:e.jsx(La,{value:a,rows:4,mono:!0,"aria-label":"Kondisi mode goal",placeholder:"mis. semua fase tercatat & plan tanpa - [ ]",onChange:r=>t(r.target.value)})})}async function He(a,t,i,r){var l;const d=((l=a.current())==null?void 0:l.lead)??se,h=s=>(s??se).engine??se.engine;a.update(s=>({...s,lead:{...s.lead??se,engine:{...h(s.lead),...i}}}));try{const s=await y.getLeadConfig(),m=await y.putLeadConfig({...s,engine:{...s.engine??se.engine,...i}});return a.update(j=>({...j,lead:m})),t==null||t(r,"ok","check-circle-2"),!0}catch{return a.update(s=>({...s,lead:d})),t==null||t("Gagal menyimpan setelan lead","err","alert-triangle"),!1}}async function Re(a,t,i,r){var l;const d=((l=a.current())==null?void 0:l.telegram)??ae,h=s=>s.engine??ae.engine;a.update(s=>({...s,telegram:{...s.telegram??ae,engine:{...h(s.telegram??ae),...i}}}));try{const s=await y.getSettings(),m=s.telegram??ae,j={...s,telegram:{...m,engine:{...m.engine??ae.engine,...i}}},p=await y.putSettings(j);return a.update(b=>({...b,telegram:(p??j).telegram??b.telegram})),t==null||t(r,"ok","check-circle-2"),!0}catch{return a.update(s=>({...s,telegram:d})),t==null||t("Gagal menyimpan setelan operator Telegram","err","alert-triangle"),!1}}function bn({s:a,store:t,onToast:i,codexVer:r,onNavigate:d}){const h=a.codex??Ce,l=a.agent??"claude",s={claude:{model:a.model,effort:a.effort},codex:{model:h.model,effort:h.effort},antigravity:a.antigravity??de},m={agent:l,...Ee({claude:{model:a.model,effort:a.effort},codex:h,antigravity:a.antigravity??de},l)},j=g=>e.jsxs(e.Fragment,{children:[g," ",e.jsx("b",{children:ne[m.agent]})," · ",e.jsx("code",{children:m.model})," · ",e.jsx("code",{children:m.effort}),"."]}),p=a.conflict??Ba,b=(g,S)=>t.save({conflict:{...p,...g}},S),f=(a.lead??se).engine??se.engine;return e.jsxs(e.Fragment,{children:[e.jsxs(M,{eyebrow:"override",title:"Override per fungsi","data-setting-card":!0,"data-search":"override per fungsi",children:[e.jsxs(G,{children:["Default global diatur di ",e.jsx("b",{children:"Sesi harian"}),". Tiap fungsi di bawah bisa memakai setelan sendiri; bila sakelarnya mati, ia ikut default global. Agen operator Telegram juga override, tetapi diatur di satu tempat bersama kredensial Telegram."]}),e.jsx("div",{className:"hn-set-inline",children:e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"send",onClick:()=>d("telegram"),children:"Buka Telegram"})})]}),e.jsx(ke,{eyebrow:"konflik",title:"Konflik rebase & merge",desc:"Saat rebase/merge berkonflik, hanoman menyerahkan worktree-nya ke satu sesi agen untuk dibereskan. Pekerjaannya sempit dan tak berfase, jadi ia boleh memakai model & effort yang berbeda dari sesi kerja. Berlaku untuk ketiga pintu integrasi: backlog, git graph, dan PRD.",toggleDesc:"Mati = ikut default global. Hidup = sesi konflik memakai pilihan di bawah.",toggleAria:"Override agen konflik",enabled:p.enabled,onToggle:g=>b({enabled:g},"Setelan konflik"+(g?" · aktif":" · ikut default global")),inheritedTestId:"conflict-inherited",inherited:j("Sesi konflik memakai default global:"),children:e.jsx(Ne,{engine:{enabled:p.enabled,agent:p.agent,model:p.model,effort:p.effort},labels:{agentTitle:"Agen",agentDesc:"Mesin yang membereskan konflik. Bisa beda dari agen sesi kerja.",effortDesc:"Konflik biasanya mekanis — effort rendah sering cukup.",aria:{agent:"Agen konflik",model:"Model konflik",effort:"Effort konflik"},msg:{agent:"Agen konflik",model:"Model konflik",effort:"Effort konflik"}},defaults:s,codexVer:r,save:(g,S)=>b(g,S)})}),e.jsx(ke,{eyebrow:"lead",title:"Agen hanoman-lead",desc:e.jsxs(e.Fragment,{children:["Mesin yang menjalankan agen pemimpin — panggilan sekali-jalan non-interaktif yang membaca docs, plan, kode, dan riwayat git sebelum memutuskan. Berlaku untuk ketiga pintu lead (kontrak, deteksi otomatis, denyut) dan dipakai putusan berikutnya, tanpa restart. Rem darurat, denyut, dan opt-in per project tetap diurus di layar ",e.jsx("b",{children:"Lead"}),"."]}),toggleDesc:"Mati = ikut default global. Hidup = lead memakai pilihan di bawah.",toggleAria:"Override agen lead",enabled:f.enabled,onToggle:g=>He(t,i,{enabled:g},"Setelan lead"+(g?" · aktif":" · ikut default global")),inheritedTestId:"lead-engine-inherited",inherited:j("hanoman-lead memakai default global:"),children:e.jsx(Ne,{engine:f,labels:{agentTitle:"Runtime",agentDesc:"Mesin yang menjalankan lead. Bisa beda dari agen sesi kerja.",effortDesc:"Putusan lead menuntut membaca bukti — dokumen proyek, ADR, plan, kode, riwayat git. Effort rendah memangkas kedalamannya.",aria:{agent:"Runtime lead",model:"Model lead",effort:"Effort lead"},msg:{agent:"Runtime lead",model:"Model lead",effort:"Effort lead"}},defaults:s,codexVer:r,save:(g,S)=>He(t,i,g,S)})}),e.jsx(ke,{eyebrow:"portal",title:"Obrolan portal klien",desc:"Permukaan obrolan di portal klien: klien memilih Brainstorming (digali sampai jelas, keluarannya PRD draft untuk Anda review) atau Bertanya (dijawab langsung dari dokumen project). Jatah berlaku per project dan dihitung bulanan; brainstorming dan pertanyaan punya jatah masing-masing.",toggleTitle:"Aktifkan obrolan",toggleDesc:"Mati = klien hanya punya Pekerjaan & Help desk, persis seperti sebelumnya.",toggleAria:"Aktifkan obrolan portal",enabled:(a.portalChat??we).enabled,onToggle:g=>t.save({portalChat:{...a.portalChat??we,enabled:g}},"Obrolan portal"+(g?" · aktif":" · mati")),children:e.jsx(jn,{s:a,store:t,onToast:i})}),e.jsx(sn,{orchestration:a.orchestration,onChange:(g,S)=>{t.save({orchestration:g},S)}})]})}function jn({s:a,store:t,onToast:i}){const r=a.portalChat??we,d=(s,m)=>t.save({portalChat:{...r,...s}},m),h=$({value:r.model,delayMs:0,save:s=>d({model:s,...Je(s,r.effort)},"Model obrolan portal → "+s)}),l=$({value:r.effort,delayMs:0,save:s=>d({effort:s},"Effort obrolan portal → "+s)});return e.jsxs(e.Fragment,{children:[e.jsx(E,{title:"Jatah brainstorming",desc:"Berapa sesi brainstorming per project tiap bulan. 0 = tertutup.",children:e.jsx(fe,{label:"Jatah brainstorming",value:r.brainstormPerMonth,min:0,max:1e3,placeholder:"mis. 3",onToast:i,onCommit:s=>d({brainstormPerMonth:s},"Jatah brainstorming → "+s)})}),e.jsx(E,{title:"Jatah pertanyaan",desc:"Berapa sesi tanya-jawab per project tiap bulan. 0 = tertutup.",children:e.jsx(fe,{label:"Jatah pertanyaan",value:r.askPerMonth,min:0,max:1e4,placeholder:"mis. 30",onToast:i,onCommit:s=>d({askPerMonth:s},"Jatah pertanyaan → "+s)})}),e.jsx(E,{title:"Model",desc:"Mesin obrolan selalu Claude — gerbang tool yang menjaganya tak ada di runtime lain.",children:e.jsx(T,{size:"sm","aria-label":"Model obrolan portal",value:h.value,className:"hn-set-w-sm",options:Ve(h.value),onChange:s=>h.set(s.target.value)})}),e.jsx(E,{title:"Effort",children:e.jsx(T,{size:"sm","aria-label":"Effort obrolan portal",value:l.value,className:"hn-set-w-xs",options:qe(h.value),onChange:s=>l.set(s.target.value)})}),e.jsx(E,{title:"Batas waktu satu jawaban",last:!0,desc:"Detik. Lewat dari ini klien menerima kalimat 'coba lagi sebentar', bukan layar menggantung.",children:e.jsx(fe,{label:"Batas waktu obrolan portal",value:r.timeoutSec,min:10,max:900,placeholder:"mis. 120",onToast:i,onCommit:s=>d({timeoutSec:s},"Batas waktu obrolan → "+s)})})]})}const fn={name:"",url:"",events:["*"],enabled:!0,allowPrivate:!1},xn=Ge.map(a=>({entity:a.entity,label:a.label,types:ge.filter(t=>t.entity===a.entity).map(t=>t.type)})),ze=a=>a?new Date(a).toLocaleString("id-ID",{dateStyle:"short",timeStyle:"medium"}):"—";function vn({e:a}){return a.enabled?e.jsx(X,{tone:"ok",children:"aktif"}):a.disabledAt?e.jsx(X,{tone:"err",children:"dinonaktifkan otomatis"}):e.jsx(X,{children:"nonaktif"})}function yn({onToast:a,onOpenDocs:t}={}){const[i,r]=c.useState(null),[d,h]=c.useState(!1),[l,s]=c.useState(null),[m,j]=c.useState(null),[p,b]=c.useState(!1),[k,f]=c.useState({}),[g,S]=c.useState(null),[P,w]=c.useState([]),{confirm:D,dialog:O}=ie(),N=c.useCallback(async()=>{try{r((await y.listWebhooks()).endpoints),h(!1)}catch{h(!0)}},[]);c.useEffect(()=>{N()},[N]);const I=async o=>{S(o);try{w((await y.listWebhookDeliveries(o)).items)}catch{w([])}},z=async()=>{if(l){b(!0);try{if(l.id)await y.updateWebhook(l.id,{name:l.name,url:l.url,events:l.events,enabled:l.enabled,allowPrivate:l.allowPrivate}),a==null||a("Endpoint webhook diperbarui");else{const o=await y.createWebhook({name:l.name,url:l.url,events:l.events,enabled:l.enabled,allowPrivate:l.allowPrivate});j(o.secret??null),a==null||a("Endpoint webhook dibuat")}s(null),await N()}catch(o){a==null||a(K("menyimpan endpoint",o),"err")}finally{b(!1)}}},C=async o=>{b(!0);try{const A=await y.updateWebhook(o,{rotateSecret:!0});j(A.secret??null),await N()}catch(A){a==null||a(`Gagal merotasi secret: ${A.message}`,"err")}finally{b(!1)}},H=async(o,A)=>{try{await y.updateWebhook(o.id,{enabled:A}),await N()}catch(B){a==null||a(K("mengubah status endpoint",B),"err")}},L=async o=>{b(!0);try{const A=await y.testWebhook(o);f(B=>({...B,[o]:A})),await N()}catch(A){f(B=>({...B,[o]:{ok:!1,httpStatus:null,durationMs:0,error:A.message}}))}finally{b(!1)}},Q=async o=>{try{await D({title:`Hapus endpoint "${o.name}"?`,message:"Endpoint ini tak lagi menerima peristiwa dari hanoman.",impact:["Riwayat pengiriman endpoint ini ikut dihapus.","Tindakan ini tak bisa dibatalkan."],confirmLabel:"Hapus endpoint",tone:"danger",icon:"trash-2",run:()=>y.deleteWebhook(o.id)})&&(a==null||a("Endpoint webhook dihapus"),await N())}catch(A){a==null||a(K("menghapus endpoint",A),"err")}},q=async o=>{try{await y.retryWebhookDelivery(o),g&&await I(g),await N()}catch(A){a==null||a(`Gagal antre ulang: ${A.message}`,"err")}},Y=(o,A)=>s(B=>B&&{...B,events:A?[...new Set([...B.events.filter(u=>u!=="*"),...o])]:B.events.filter(u=>u!=="*"&&!o.includes(u))}),U=(l==null?void 0:l.events.includes("*"))??!1;return e.jsxs(e.Fragment,{children:[e.jsxs(M,{eyebrow:"integrasi",title:"Webhook keluar",children:[e.jsxs("div",{className:"hn-wh-muted hn-wh-mb12",children:["hanoman mengirim ",e.jsx("b",{children:"HTTP POST"})," bertanda tangan ke endpoint yang Anda daftarkan setiap kali sesuatu berubah — backlog dibuat atau berpindah stage, sesi mulai dan selesai, putusan lead terbit, tiket masuk, notifikasi. Pengiriman berjalan di antrean: penerima yang lambat atau mati ",e.jsx("b",{children:"tidak"})," memperlambat hanoman."]}),e.jsxs("div",{className:"hn-wh-actions",children:[e.jsxs(x,{size:"sm",onClick:()=>{s({...fn}),j(null)},children:[e.jsx(le,{name:"plus",size:14})," Tambah endpoint"]}),t&&e.jsxs(x,{size:"sm",variant:"ghost",onClick:t,children:[e.jsx(le,{name:"book-open",size:14})," Dokumentasi webhook"]})]}),d?e.jsx(W,{kind:"error",compact:!0,title:"Gagal memuat endpoint webhook",hint:"Coba muat ulang.",action:()=>void N(),actionLabel:"Coba lagi"}):i===null?e.jsx("div",{className:"hn-wh-muted",children:"Memuat…"}):i.length===0?e.jsx(W,{kind:"empty",compact:!0,title:"Belum ada endpoint webhook",hint:"Daftarkan URL penerima pertama untuk mulai berlangganan peristiwa hanoman."}):e.jsx("div",{className:"hn-wh-col-10",children:i.map(o=>e.jsxs("div",{"data-testid":`webhook-${o.id}`,className:"hn-wh-endpoint",children:[e.jsxs("div",{className:"hn-wh-endpoint-head",children:[e.jsx("div",{className:"hn-wh-name",children:o.name}),e.jsx(vn,{e:o}),o.pending>0?e.jsxs(X,{children:[o.pending," mengantre"]}):null,e.jsxs("div",{className:"hn-wh-endpoint-actions",children:[e.jsx(J,{checked:o.enabled,"aria-label":`Aktifkan ${o.name}`,onChange:A=>void H(o,A)}),e.jsx(x,{size:"sm",variant:"ghost",disabled:p,onClick:()=>void L(o.id),children:"Test"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>void I(o.id),children:"Riwayat"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>{j(null),s({id:o.id,name:o.name,url:o.url,events:o.events,enabled:o.enabled,allowPrivate:o.allowPrivate})},children:"Ubah"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>void Q(o),children:"Hapus"})]})]}),e.jsx("div",{className:"hn-wh-url",children:o.url}),e.jsxs("div",{className:"hn-wh-muted hn-wh-mt6",children:["Peristiwa: ",e.jsx("code",{children:o.events.join(", ")})," · secret …",o.secretHint," ·"," ","sukses terakhir ",ze(o.lastSuccessAt),o.failureStreak>0?` · ${o.failureStreak} gagal beruntun`:""]}),o.disabledReason?e.jsx("div",{className:"hn-wh-muted hn-wh-mt6 hn-wh-err",children:o.disabledReason}):null,k[o.id]?e.jsx("div",{className:"hn-wh-muted hn-wh-mt6",children:k[o.id].ok?`Test berhasil — HTTP ${k[o.id].httpStatus} · ${k[o.id].durationMs} ms`:`Test gagal — ${k[o.id].error}`}):null]},o.id))})]}),m?e.jsxs(M,{eyebrow:"secret",title:"Salin sekarang — secret tak ditampilkan lagi",children:[e.jsx(te,{tone:"brass",children:e.jsx("div",{className:"hn-wh-secret",children:m})}),e.jsxs("div",{className:"hn-wh-row hn-wh-mt10",children:[e.jsx(x,{size:"sm",onClick:()=>{var o;return void((o=navigator.clipboard)==null?void 0:o.writeText(m))},children:"Salin secret"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>j(null),children:"Tutup"})]})]}):null,l?e.jsx(M,{eyebrow:l.id?"ubah":"tambah",title:l.id?"Ubah endpoint":"Endpoint baru",children:e.jsxs("div",{className:"hn-wh-col-12",children:[e.jsx(Z,{label:"Nama",children:e.jsx(V,{value:l.name,placeholder:"mis. Dashboard internal",onChange:o=>s({...l,name:o.target.value})})}),e.jsx(Z,{label:"URL tujuan",children:e.jsx(V,{value:l.url,placeholder:"https://contoh.id/hanoman-webhook",onChange:o=>s({...l,url:o.target.value})})}),e.jsxs("div",{children:[e.jsx("div",{className:"hn-wh-label",children:"Peristiwa yang dikirim"}),e.jsx(oe,{checked:U,label:"Semua peristiwa",onChange:o=>s({...l,events:o?["*"]:[]})}),U?null:e.jsxs("div",{className:"hn-wh-tree",children:[xn.map(o=>e.jsxs("div",{children:[e.jsx(oe,{checked:o.types.every(A=>l.events.includes(A)),label:o.label,onChange:A=>Y(o.types,A)}),e.jsx("div",{className:"hn-wh-family-types",children:o.types.map(A=>e.jsx(oe,{checked:l.events.includes(A),label:A,onChange:B=>s({...l,events:B?[...new Set([...l.events.filter(u=>u!=="*"),A])]:l.events.filter(u=>u!==A&&u!=="*")})},A))})]},o.entity)),e.jsxs("div",{className:"hn-wh-muted",children:[e.jsx("code",{children:Ha})," selalu terkirim saat tombol Test ditekan, apa pun langganannya."]})]})]}),e.jsx(oe,{checked:l.allowPrivate,label:"Izinkan alamat internal / loopback",onChange:o=>s({...l,allowPrivate:o})}),e.jsx("div",{className:"hn-wh-muted",children:"Biarkan mati kecuali penerima memang berjalan di mesin/jaringan yang sama. Menyalakannya membuka jalan ke layanan internal yang tak pernah dimaksudkan terekspos."}),e.jsx(oe,{checked:l.enabled,label:"Aktif",onChange:o=>s({...l,enabled:o})}),e.jsxs("div",{className:"hn-wh-row",children:[e.jsx(x,{size:"sm",disabled:p||!l.name||!l.url||l.events.length===0,onClick:()=>void z(),children:"Simpan"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>s(null),children:"Batal"}),l.id?e.jsx(x,{size:"sm",variant:"ghost",disabled:p,onClick:()=>void C(l.id),children:"Rotasi secret"}):null]})]})}):null,g?e.jsxs(M,{eyebrow:"riwayat",title:"Riwayat pengiriman",children:[e.jsx("div",{className:"hn-wh-history-head",children:e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>S(null),children:"Tutup riwayat"})}),P.length===0?e.jsx("div",{className:"hn-wh-muted",children:"Belum ada pengiriman."}):e.jsx("div",{className:"hn-local-overflow",children:e.jsxs("table",{className:"hn-wh-table hn-wh-table--full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"hn-wh-thead",children:[e.jsx("th",{className:"hn-wh-cell",children:"Waktu"}),e.jsx("th",{className:"hn-wh-cell",children:"Jenis"}),e.jsx("th",{className:"hn-wh-cell",children:"Status"}),e.jsx("th",{className:"hn-wh-cell",children:"HTTP"}),e.jsx("th",{className:"hn-wh-cell",children:"Percobaan"}),e.jsx("th",{className:"hn-wh-cell",children:"Galat"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:P.map(o=>e.jsxs("tr",{className:"hn-wh-tr",children:[e.jsx("td",{className:"hn-wh-cell hn-wh-cell--nowrap",children:ze(o.createdAt)}),e.jsx("td",{className:"hn-wh-cell hn-wh-cell--mono12",children:o.eventType}),e.jsx("td",{className:"hn-wh-cell",children:o.status}),e.jsx("td",{className:"hn-wh-cell",children:o.httpStatus??"—"}),e.jsx("td",{className:"hn-wh-cell",children:`${o.attempt} / ${o.maxAttempts}`}),e.jsx("td",{className:"hn-wh-cell hn-wh-cell--muted",children:o.error??"—"}),e.jsx("td",{className:"hn-wh-cell",children:o.status==="failed"||o.status==="dropped"?e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>void q(o.id),children:"Antre ulang"}):null})]},o.id))})]})})]}):null,O]})}function ve({text:a,label:t="Salin"}){const[i,r]=c.useState(!1);return e.jsxs("div",{className:"hn-wh-copy",children:[e.jsx("pre",{className:"hn-wh-code",children:a}),e.jsx("div",{className:"hn-wh-mt6",children:e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>{var d;(d=navigator.clipboard)==null||d.writeText(a),r(!0),setTimeout(()=>r(!1),1500)},children:i?"Tersalin":t})})]})}const wn=`// Node.js (Express) — verifikasi tanda tangan webhook hanoman
1
+ import{bt as ea,bu as aa,bv as na,bw as ta,bx as ia,by as sa,bz as la,bA as ra,bB as da,bC as ca,bD as oa,bE as ua,bF as ha,bG as ma,bH as ga,bI as ka,bJ as pa,bK as ba,bL as ja,bM as fa,bN as xa,bO as va,bP as ya,h as y,i as K,j as e,f as V,bQ as wa,bR as Sa,a7 as Ce,bS as Na,a6 as de,af as Ca,bT as Ea,a8 as Ee,aL as M,b4 as J,g as T,B as x,bU as Pe,bi as Aa,a_ as be,a9 as Oa,aa as Pa,ab as Ma,bV as Ia,bW as Da,bX as _a,bY as Me,bZ as Ie,n as X,H as La,b_ as ae,b$ as se,c0 as Ba,c1 as we,d as ie,I as le,m as W,C as te,e as Z,ac as oe,c2 as Ha,c3 as Ge,c4 as ge,c5 as Ue,c6 as Ra,c7 as ue,c8 as Ae,c9 as za,ca as De,cb as Fa,cc as $a,cd as Ka,ce as pe,$ as Ga,b as Te,cf as Ua,cg as Ta,ch as Wa,ai as Se,q as Ja,D as Va,ci as qa,cj as Ya}from"./index-C4Py9MJV.js";import{R as c}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import{S as Oe,s as We,u as $,c as Je,a as E,b as _e,P as G,d as je,e as ne,A as Qa,f as Ve,g as qe,C as Xa,h as Za,F as ke,E as Ne,N as fe,B as he,i as en,n as Le,j as an,r as nn,D as tn}from"./fields-BY7SYerd.js";import{r as Ye,O as sn}from"./settings-rebase-C3611gs8.js";import{D as ln}from"./DocPreviewModal-CbhkDUJ2.js";import"./xterm-3VOAfa_q.js";/* empty css */const rn=[...ea,...aa,...na,...ta,...ia,...sa,...la,...ra,...da,...ca,...oa,...ua,...ha,...ma,...ga,...ka,...pa,...ba,...ja,...fa,...xa,...va,...ya],dn=2,Be=()=>{};function cn(a){const[t,i]=c.useState(null),[r,d]=c.useState(!1),h=c.useRef(null),l=c.useRef(a);l.current=a;const s=c.useRef(Promise.resolve()),m=c.useCallback(g=>{h.current=g,i(g)},[]),j=c.useCallback(()=>{d(!1),m(null),y.getSettings().then(g=>m(g),()=>d(!0))},[m]);c.useEffect(()=>{j()},[j]);const p=c.useCallback((g,S,P,w)=>{const D=h.current;if(!D)return Promise.resolve(!1);const O=Object.keys(g).filter(I=>JSON.stringify(g[I])!==JSON.stringify(D[I]));m(g);const N=s.current.then(async()=>{const I=await y.getSettings().catch(()=>{});await y.putSettings(Ye(D,g,I))});return s.current=N.then(Be,Be),N.then(()=>{var I;return S&&((I=l.current)==null||I.call(l,S,P||"ok",w||"check-circle-2")),!0},I=>{var C;const z=Object.fromEntries(O.map(H=>[H,D[H]]));return m({...h.current??D,...z}),(C=l.current)==null||C.call(l,K("menyimpan pengaturan",I),"err","alert-triangle"),!1})},[m]),b=c.useCallback((g,S)=>{const P=h.current;return P?p({...P,...g},S):Promise.resolve(!1)},[p]),k=c.useCallback(g=>{const S=h.current;S&&m(g(S))},[m]),f=c.useCallback(()=>h.current,[]);return{s:t,failed:r,load:j,persist:p,save:b,update:k,current:f}}function on(a){const t=a.trim().toLowerCase();return t?Oe.flatMap(i=>i.sections).filter(i=>`${i.label} ${i.keywords}`.toLowerCase().includes(t)).map(i=>({key:i.key,path:We(i.key)})):[]}const xe=(a,t)=>(a??"").toLowerCase().includes(t);function un(a,t){if(!a)return 0;const i=t.trim().toLowerCase(),r=Array.from(a.querySelectorAll("[data-setting-row]")),d=Array.from(a.querySelectorAll("[data-setting-card]")),h=s=>{var m;return((m=s.parentElement)==null?void 0:m.closest("[data-setting-card]"))??null};let l=0;return i?(d.forEach(s=>{const m=xe(s.getAttribute("data-search"),i),j=Array.from(s.querySelectorAll("[data-setting-row]")).filter(b=>h(b)===s);if(j.length===0){s.hidden=!m,m&&l++;return}let p=!1;j.forEach(b=>{const k=m||xe(b.getAttribute("data-search"),i);b.hidden=!k,k&&(p=!0,l++)}),s.hidden=!(m||p)}),r.forEach(s=>{if(h(s))return;const m=xe(s.getAttribute("data-search"),i);s.hidden=!m,m&&l++}),l):(r.forEach(s=>{s.hidden=!1}),d.forEach(s=>{s.hidden=!1}),r.length+d.filter(s=>!s.querySelector("[data-setting-row]")).length)}function hn(a,t,i){const[r,d]=c.useState(0);return c.useLayoutEffect(()=>{const h=a.current,l=()=>d(un(h,t));if(l(),!h||typeof MutationObserver>"u")return;const s=new MutationObserver(l);return s.observe(h,{childList:!0,subtree:!0}),()=>s.disconnect()},[t,i,a]),r}function mn({value:a,onChange:t,hits:i,onPick:r}){return e.jsxs("div",{className:"hn-set-search",role:"search",children:[e.jsx(V,{type:"search","aria-label":"Cari pengaturan",placeholder:"mis. notifikasi, telegram, token",value:a,leftIcon:"search",className:"hn-set-full",onChange:d=>t(d.target.value),onKeyDown:d=>{d.key==="Escape"&&a&&t("")}}),a.trim()!==""&&i.length>0&&e.jsx("ul",{className:"hn-set-search-hits","aria-label":"Bagian yang cocok",children:i.map(d=>e.jsx("li",{children:e.jsx("button",{type:"button",className:"hn-set-search-hit",onClick:()=>r(d.key),children:d.path})},d.key))})]})}const gn={default:null,tampil:!0,sembunyi:!1};function re(a,t,i,r){return $({value:i,delayMs:0,save:d=>a.save({[t]:d},r+(d?" · aktif":" · nonaktif"))})}function kn({s:a,store:t,onToast:i,codexVer:r}){const d=wa(),[h,l]=c.useState(null),[s,m]=c.useState("");c.useEffect(()=>{y.getMethodStatus().then(l).catch(()=>l(null)),y.listProjects({limit:100}).then(n=>m(v=>{var F;return v||(((F=n.items.find(ce=>ce.binding??ce.repoDir))==null?void 0:F.id)??"")})).catch(n=>i==null?void 0:i(K("memuat daftar project",n),"err","alert-triangle"))},[]);const[j,p]=Sa(),b=j===null?"default":j?"tampil":"sembunyi",k=re(t,"notifyDone",a.notifyDone,"Notifikasi backlog selesai"),f=$({value:a.notifySound,delayMs:0,save:n=>t.save({notifySound:n},"Sound → "+n)}),g=re(t,"notifyDecision",a.notifyDecision,"Notifikasi keputusan"),S=re(t,"notifyDecisionTelegram",a.notifyDecisionTelegram,"Keputusan ke Telegram"),P=$({value:a.notifyDecisionSound,delayMs:0,save:n=>t.save({notifyDecisionSound:n},"Sound keputusan → "+n)}),w=re(t,"notifyFail",a.notifyFail,"Notifikasi gagal"),D=re(t,"autoDefault",a.autoDefault,"Full-auto default"),O=re(t,"autoScaffold",a.autoScaffold,"Auto-scaffold"),N=a.agent??"claude",I=a.codex??Ce,z=$({value:N,delayMs:0,save:n=>t.save({agent:n},"Agen → "+n)}),C=$({value:a.model,delayMs:0,save:n=>t.save({model:n,...Je(n,a.effort)},"Model claude → "+n)}),H=$({value:a.effort,delayMs:0,save:n=>t.save({effort:n},"Effort claude → "+n)}),L=$({value:I.model,delayMs:0,save:n=>t.save({codex:{model:n,effort:Na(n,I.effort)}},"Model codex → "+n)}),Q=$({value:I.effort,delayMs:0,save:n=>t.save({codex:{...I,effort:n}},"Effort codex → "+n)}),q=a.antigravity??de,Y=$({value:q.model,delayMs:0,save:n=>t.save({antigravity:{model:n,effort:Ca("antigravity",n,q.effort)}},"Model Antigravity → "+n)}),U=$({value:q.effort,delayMs:0,save:n=>t.save({antigravity:{...q,effort:n}},"Effort Antigravity → "+n)}),o=$({value:a.goal.enabled,delayMs:0,save:n=>t.save({goal:{...a.goal,enabled:n}},"Mode goal"+(n?" · aktif":" · nonaktif"))}),A=$({value:a.goal.condition,save:n=>t.save({goal:{...a.goal,condition:n}},"Kondisi mode goal disimpan")}),B=$({value:a.verifyScope??"changed",delayMs:0,save:n=>t.save({verifyScope:n},"Scope verifikasi → "+n)}),u=$({value:Ea(a.method).id,delayMs:0,save:n=>t.save({method:n},"Metode → "+n)}),_=async n=>{if(s)try{await y.createShell(s,{method:n.method,agent:n.agent}),i==null||i(`Pemasangan ${n.label} · ${ne[n.agent]} berjalan di Terminal`,"ok","terminal")}catch{i==null||i("Gagal membuka sesi terminal pemasangan","err","alert-triangle")}},R={agent:N,...Ee({claude:{model:a.model,effort:a.effort},codex:I,antigravity:a.antigravity??de},N)};return e.jsxs(e.Fragment,{children:[e.jsxs(M,{eyebrow:"sesi",title:"Sesi & notifikasi","data-setting-card":!0,"data-search":"sesi notifikasi suara telegram keputusan",children:[e.jsx(E,{title:"Notifikasi backlog selesai",desc:"Toast + sound saat sebuah backlog mencapai stage done. Daftar lonceng tetap terisi meski dimatikan.",save:k,children:e.jsx(J,{"aria-label":"Notifikasi backlog selesai",checked:k.value,onChange:n=>k.set(n)})}),e.jsx(E,{title:"Sound notifikasi",desc:"Durasi nada saat backlog selesai.",save:f,children:e.jsxs("div",{className:"hn-set-inline",children:[e.jsx(T,{size:"sm","aria-label":"Sound notifikasi",value:f.value,options:_e,className:"hn-set-w-sm",onChange:n=>f.set(n.target.value)}),e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"volume-2",disabled:f.value==="off",onClick:()=>Pe(f.value),children:"Preview"})]})}),e.jsx(E,{title:"Notifikasi butuh keputusan",desc:"Toast + sound saat sesi Claude berhenti menunggu keputusanmu. Nada sengaja beda dari selesai.",save:g,children:e.jsx(J,{"aria-label":"Notifikasi keputusan",checked:g.value,onChange:n=>g.set(n)})}),e.jsx(E,{title:"Kirim keputusan ke Telegram",desc:"Pesan ke user id di allowlist Telegram saat sesi menunggu keputusanmu, supaya tak menunggu sampai dashboard dibuka. Perlu bot token + allowlist; gateway percakapan tak perlu berjalan.",save:S,children:e.jsx(J,{"aria-label":"Kirim keputusan ke Telegram",checked:S.value,onChange:n=>S.set(n)})}),e.jsx(E,{title:"Sound keputusan",desc:"Nada saat sebuah sesi menunggu keputusan.",save:P,children:e.jsxs("div",{className:"hn-set-inline",children:[e.jsx(T,{size:"sm","aria-label":"Sound keputusan",value:P.value,options:_e,className:"hn-set-w-sm",onChange:n=>P.set(n.target.value)}),e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"volume-2",disabled:P.value==="off",onClick:()=>Pe(P.value),children:"Preview"})]})}),e.jsx(E,{title:"Notifikasi saat sesi gagal",last:!0,desc:"Kirim notifikasi ketika sesi Claude Code berakhir dengan error.",save:w,children:e.jsx(J,{"aria-label":"Notifikasi gagal",checked:w.value,onChange:n=>w.set(n)})})]}),e.jsxs(M,{eyebrow:"umum",title:"Perilaku sesi","data-setting-card":!0,"data-search":"perilaku sesi full-auto scaffold doc index",children:[e.jsx(E,{title:"Full-auto sebagai default",desc:"Run baru jalan sendiri sampai selesai. Manusia tetap bisa steer / interupsi kapan pun.",save:D,children:e.jsx(J,{"aria-label":"Full-auto sebagai default",checked:D.value,onChange:n=>D.set(n)})}),e.jsx(E,{title:"Auto-scaffold doc index",desc:"Project yang dibuat dari nol otomatis disiapkan indeks dokumennya setelah tujuannya terkunci.",save:O,children:e.jsx(J,{"aria-label":"Auto-scaffold",checked:O.value,onChange:n=>O.set(n)})}),e.jsx(E,{title:"Tampilkan Hanoman (pet)",last:!0,search:"pet hanoman maskot tampil sembunyi",desc:"Pendamping kecil di sudut layar. Pilihan ini hanya berlaku di browser ini. Default: aktif di desktop, mati di tablet & ponsel.",children:e.jsxs(Aa,{"aria-label":"Tampilkan Hanoman (pet)",direction:"row",value:b,onChange:n=>p(gn[n]??null),children:[e.jsx(be,{value:"default",label:"Default"}),e.jsx(be,{value:"tampil",label:"Tampilkan"}),e.jsx(be,{value:"sembunyi",label:"Sembunyikan"})]})})]}),e.jsxs(M,{eyebrow:"model",title:"Agen & model — default global","data-setting-card":!0,"data-search":"agen model default effort claude codex agen sesi baru",children:[e.jsxs(G,{children:["Default untuk sesi baru; bisa di-override per sesi saat ",e.jsx("b",{children:"Start"}),". Di terminal, ",e.jsx("code",{children:"/model"})," ","mengubahnya kapan saja. Dengan orkestrasi aktif, model ini menjadi model ",e.jsx("b",{children:"orchestrator"}),"; model & effort tiap fase diatur di bagian ",e.jsx("b",{children:"Orkestrasi"})," pada Agen & model. Yang benar-benar dipakai adalah blok milik agen terpilih di bawah — blok runtime lain tersimpan, menunggu giliran."]}),e.jsx(E,{title:"Agen default",desc:"Sesi backlog masih bisa memilih agen lain saat Start.",save:z,children:e.jsx(T,{size:"sm","aria-label":"Agen default",value:z.value,className:"hn-set-w-sm",options:Oa,onChange:n=>z.set(n.target.value)})}),e.jsxs("div",{"data-testid":"agent-group-antigravity",className:"hn-set-group",children:[e.jsx(je,{id:"antigravity",label:ne.antigravity,active:N==="antigravity"}),e.jsx(Qa,{}),e.jsx(E,{title:"Model",desc:"Model parent diteruskan ke agy --model.",save:Y,children:e.jsx(T,{size:"sm","aria-label":"Model antigravity",value:Y.value,options:Pa("antigravity",Y.value),onChange:n=>Y.set(n.target.value)})}),e.jsx(E,{title:"Effort",last:!0,desc:"Effort mengikuti kemampuan slug model parent.",save:U,children:e.jsx(T,{size:"sm","aria-label":"Effort antigravity",value:U.value,options:Ma("antigravity",Y.value).map(n=>({value:n,label:n})),onChange:n=>U.set(n.target.value)})})]}),e.jsxs("div",{"data-testid":"agent-group-claude",className:"hn-set-group",children:[e.jsxs("div",{className:"hn-set-catalog",children:["Katalog model diperiksa otomatis setiap 5 menit.",Object.entries(d.providers).map(([n,v])=>e.jsxs("div",{children:[n,": ",v.source==="bundled"?"daftar bawaan":v.source==="cache"?"cache terakhir":"dari CLI",v.checkedAt?" · diperiksa "+new Date(v.checkedAt).toLocaleTimeString():"",v.error?" · "+v.error:""]},n))]}),e.jsx(je,{id:"claude",label:ne.claude,active:N==="claude"}),e.jsx(E,{title:"Model",desc:"Diteruskan apa adanya ke `claude --model`.",save:C,children:e.jsx(T,{size:"sm","aria-label":"Model claude",value:C.value,options:Ve(C.value),className:"hn-set-w-sm",onChange:n=>C.set(n.target.value)})}),e.jsx(E,{title:"Effort",last:!0,desc:"Anggaran berpikir per giliran (`claude --effort`).",save:H,children:e.jsx(T,{size:"sm","aria-label":"Effort claude",value:H.value,options:qe(C.value),className:"hn-set-w-xs",onChange:n=>H.set(n.target.value)})})]}),e.jsxs("div",{"data-testid":"agent-group-codex",className:"hn-set-group hn-set-group--codex",children:[e.jsx(je,{id:"codex",label:ne.codex,active:N==="codex"}),e.jsx(Xa,{model:L.value,codexVer:r}),e.jsx(E,{title:"Model",desc:"Diteruskan apa adanya ke `codex -m`.",save:L,children:e.jsx(T,{size:"sm","aria-label":"Model codex",value:L.value,className:"hn-set-w-sm",options:Ia(Da,L.value),onChange:n=>L.set(n.target.value)})}),e.jsx(E,{title:"Effort",last:!0,desc:"Diteruskan ke `codex -c model_reasoning_effort`.",save:Q,children:e.jsx(T,{size:"sm","aria-label":"Effort codex",value:Q.value,className:"hn-set-w-xs",options:_a(L.value).map(n=>({value:n,label:n})),onChange:n=>Q.set(n.target.value)})})]}),e.jsxs("div",{className:"hn-set-inherited-note","data-testid":"session-default-summary",children:["Sesi baru memakai ",e.jsx("b",{children:ne[R.agent]})," · ",e.jsx("code",{children:R.model})," · ",e.jsx("code",{children:R.effort}),"."]})]}),e.jsxs(M,{eyebrow:"goal",title:"Mode goal — sesi backlog","data-setting-card":!0,"data-search":"mode goal kondisi template gate stop",children:[N==="antigravity"&&e.jsx(G,{children:"Mode goal native Antigravity belum didukung. Nilai global tetap disimpan; matikan mode goal secara eksplisit atau pilih runtime lain sebelum memulai sesi."}),e.jsxs(G,{children:["Sesi backlog lahir dengan gate ",e.jsx("code",{children:"Stop"}),": ia menolak berhenti sampai kondisinya terbukti di transkrip. Interupsi manusia (",e.jsx("code",{children:"Esc"}),") tetap bekerja; melepas gate sepenuhnya = hentikan sesinya. Sesi scheduler mengikuti setelan ini."]}),e.jsx(E,{title:"Aktif sebagai default",desc:"Sesi backlog baru lahir dengan mode goal. Masih bisa dimatikan per sesi saat Start.",save:o,children:e.jsx(J,{"aria-label":"Mode goal default",disabled:N==="antigravity"&&!o.value,checked:o.value,onChange:n=>o.set(n)})}),e.jsx(E,{title:"Kondisi (template global)",last:!0,desc:"Kosong = kondisi bawaan hanoman: semua fase tercatat di phase file, plan tak menyisakan task, push sukses.",save:A,children:e.jsx("div",{className:"hn-set-w-field",children:e.jsx(pn,{value:A.value,onSet:A.set,onFlush:A.flush})})})]}),e.jsxs(M,{eyebrow:"verifikasi",title:"Scope verifikasi — sesi backlog","data-setting-card":!0,"data-search":"scope verifikasi hanya yang berubah seluruh project uji jangan jalankan test",children:[e.jsxs(G,{children:["Beberapa sesi berjalan bersamaan di perangkat ini. ",e.jsx("b",{children:"Hanya yang berubah"})," menyuruh sesi menguji hanya berkas yang ia ubah — misalnya dengan ",e.jsx("code",{children:"vitest --changed"})," (uji) dan typecheck per paket — alih-alih seluruh project. Dengan begitu RAM dan CPU tetap tersisa untuk sesi lain. Uji penuh, lint penuh, dan build penuh tetap dijalankan manusia sebelum merge. Bila perangkat tak kuat menjalankan test sama sekali, pilih ",e.jsx("b",{children:"Jangan jalankan test"}),": sesi tetap menulis test, tapi memverifikasi dengan membaca kode dan menyerahkan run test ke manusia."]}),e.jsx(E,{title:"Scope default",last:!0,desc:"Sesi backlog baru lahir dengan scope ini. Masih bisa diubah per sesi saat Start.",save:B,children:e.jsx(T,{size:"sm","aria-label":"Scope verifikasi default",value:B.value,className:"hn-set-w-md",options:[{value:"changed",label:"Hanya yang berubah"},{value:"full",label:"Seluruh project"},{value:"none",label:"Jangan jalankan test"}],onChange:n=>B.set(n.target.value)})})]}),e.jsxs(M,{eyebrow:"metode",title:"Metode workflow — sesi backlog","data-setting-card":!0,"data-search":"metode workflow skill direktori plan spec pemasangan",children:[e.jsxs(G,{children:["Metode menentukan ",e.jsx("b",{children:"skill mana yang dimuat di tiap fase"})," dan ",e.jsx("b",{children:"di direktori mana plan & spec ditulis"}),". Fase-fasenya sendiri tak berubah. Gerbang plan memindai direktori SEMUA metode, jadi item yang berpindah metode tak pernah lolos lewat direktori kosong."]}),e.jsx(E,{title:"Metode default",last:!0,desc:"Sesi backlog baru lahir dengan metode ini. Masih bisa diubah per sesi saat Start.",save:u,children:e.jsx(T,{size:"sm","aria-label":"Metode default",className:"hn-set-w-md",value:u.value,options:Me.map(n=>({value:n,label:Ie[n].label})),onChange:n=>u.set(n.target.value)})}),h&&e.jsxs("div",{"data-testid":"method-status",className:"hn-set-method-status",children:[Me.map(n=>e.jsxs("div",{className:"hn-set-method",children:[e.jsx("div",{className:"hn-set-method-name",children:Ie[n].label}),h.methods.filter(v=>v.method===n).map(v=>e.jsxs("div",{"data-testid":`method-status-${v.method}-${v.agent}`,className:"hn-set-method-row",children:[e.jsx(X,{tone:v.ready?"ok":"warn",children:v.ready?"siap":"belum siap"}),e.jsxs("div",{className:"hn-set-method-text",children:[e.jsx("b",{children:ne[v.agent]}),v.availabilityReason&&e.jsx("div",{children:v.availabilityReason}),!v.ready&&e.jsxs("div",{className:"hn-set-method-missing",children:[v.missingPackages.length>0&&e.jsxs("div",{children:["paket kurang: ",e.jsx("code",{children:v.missingPackages.join(" · ")})]}),v.missingSkills.length>0&&e.jsxs("div",{children:["skill kurang: ",e.jsx("code",{children:v.missingSkills.join(" · ")})]})]})]}),!v.ready&&e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"download",disabled:!s||v.available===!1,onClick:()=>_(v),children:"Pasang"})]},v.agent))]},n)),e.jsx(Za,{children:s?e.jsxs(e.Fragment,{children:["Pemasangan berjalan di ",e.jsx("b",{children:"sesi terminal"})," project ",e.jsx("code",{children:s})," — outputnya bisa ditonton di Terminal. hanoman sendiri tak pernah memasang apa pun."]}):e.jsx(e.Fragment,{children:"Pemasangan butuh satu project yang sudah di-bind ke checkout lokal: perintahnya dijalankan di sesi terminal project itu."})})]})]})]})}function pn({value:a,onSet:t,onFlush:i}){return e.jsx("div",{onBlur:()=>i(),children:e.jsx(La,{value:a,rows:4,mono:!0,"aria-label":"Kondisi mode goal",placeholder:"mis. semua fase tercatat & plan tanpa - [ ]",onChange:r=>t(r.target.value)})})}async function He(a,t,i,r){var l;const d=((l=a.current())==null?void 0:l.lead)??se,h=s=>(s??se).engine??se.engine;a.update(s=>({...s,lead:{...s.lead??se,engine:{...h(s.lead),...i}}}));try{const s=await y.getLeadConfig(),m=await y.putLeadConfig({...s,engine:{...s.engine??se.engine,...i}});return a.update(j=>({...j,lead:m})),t==null||t(r,"ok","check-circle-2"),!0}catch{return a.update(s=>({...s,lead:d})),t==null||t("Gagal menyimpan setelan lead","err","alert-triangle"),!1}}async function Re(a,t,i,r){var l;const d=((l=a.current())==null?void 0:l.telegram)??ae,h=s=>s.engine??ae.engine;a.update(s=>({...s,telegram:{...s.telegram??ae,engine:{...h(s.telegram??ae),...i}}}));try{const s=await y.getSettings(),m=s.telegram??ae,j={...s,telegram:{...m,engine:{...m.engine??ae.engine,...i}}},p=await y.putSettings(j);return a.update(b=>({...b,telegram:(p??j).telegram??b.telegram})),t==null||t(r,"ok","check-circle-2"),!0}catch{return a.update(s=>({...s,telegram:d})),t==null||t("Gagal menyimpan setelan operator Telegram","err","alert-triangle"),!1}}function bn({s:a,store:t,onToast:i,codexVer:r,onNavigate:d}){const h=a.codex??Ce,l=a.agent??"claude",s={claude:{model:a.model,effort:a.effort},codex:{model:h.model,effort:h.effort},antigravity:a.antigravity??de},m={agent:l,...Ee({claude:{model:a.model,effort:a.effort},codex:h,antigravity:a.antigravity??de},l)},j=g=>e.jsxs(e.Fragment,{children:[g," ",e.jsx("b",{children:ne[m.agent]})," · ",e.jsx("code",{children:m.model})," · ",e.jsx("code",{children:m.effort}),"."]}),p=a.conflict??Ba,b=(g,S)=>t.save({conflict:{...p,...g}},S),f=(a.lead??se).engine??se.engine;return e.jsxs(e.Fragment,{children:[e.jsxs(M,{eyebrow:"override",title:"Override per fungsi","data-setting-card":!0,"data-search":"override per fungsi",children:[e.jsxs(G,{children:["Default global diatur di ",e.jsx("b",{children:"Sesi harian"}),". Tiap fungsi di bawah bisa memakai setelan sendiri; bila sakelarnya mati, ia ikut default global. Agen operator Telegram juga override, tetapi diatur di satu tempat bersama kredensial Telegram."]}),e.jsx("div",{className:"hn-set-inline",children:e.jsx(x,{size:"sm",variant:"ghost",leftIcon:"send",onClick:()=>d("telegram"),children:"Buka Telegram"})})]}),e.jsx(ke,{eyebrow:"konflik",title:"Konflik rebase & merge",desc:"Saat rebase/merge berkonflik, hanoman menyerahkan worktree-nya ke satu sesi agen untuk dibereskan. Pekerjaannya sempit dan tak berfase, jadi ia boleh memakai model & effort yang berbeda dari sesi kerja. Berlaku untuk ketiga pintu integrasi: backlog, git graph, dan PRD.",toggleDesc:"Mati = ikut default global. Hidup = sesi konflik memakai pilihan di bawah.",toggleAria:"Override agen konflik",enabled:p.enabled,onToggle:g=>b({enabled:g},"Setelan konflik"+(g?" · aktif":" · ikut default global")),inheritedTestId:"conflict-inherited",inherited:j("Sesi konflik memakai default global:"),children:e.jsx(Ne,{engine:{enabled:p.enabled,agent:p.agent,model:p.model,effort:p.effort},labels:{agentTitle:"Agen",agentDesc:"Mesin yang membereskan konflik. Bisa beda dari agen sesi kerja.",effortDesc:"Konflik biasanya mekanis — effort rendah sering cukup.",aria:{agent:"Agen konflik",model:"Model konflik",effort:"Effort konflik"},msg:{agent:"Agen konflik",model:"Model konflik",effort:"Effort konflik"}},defaults:s,codexVer:r,save:(g,S)=>b(g,S)})}),e.jsx(ke,{eyebrow:"lead",title:"Agen hanoman-lead",desc:e.jsxs(e.Fragment,{children:["Mesin yang menjalankan agen pemimpin — panggilan sekali-jalan non-interaktif yang membaca docs, plan, kode, dan riwayat git sebelum memutuskan. Berlaku untuk ketiga pintu lead (kontrak, deteksi otomatis, denyut) dan dipakai putusan berikutnya, tanpa restart. Rem darurat, denyut, dan opt-in per project tetap diurus di layar ",e.jsx("b",{children:"Lead"}),"."]}),toggleDesc:"Mati = ikut default global. Hidup = lead memakai pilihan di bawah.",toggleAria:"Override agen lead",enabled:f.enabled,onToggle:g=>He(t,i,{enabled:g},"Setelan lead"+(g?" · aktif":" · ikut default global")),inheritedTestId:"lead-engine-inherited",inherited:j("hanoman-lead memakai default global:"),children:e.jsx(Ne,{engine:f,labels:{agentTitle:"Runtime",agentDesc:"Mesin yang menjalankan lead. Bisa beda dari agen sesi kerja.",effortDesc:"Putusan lead menuntut membaca bukti — dokumen proyek, ADR, plan, kode, riwayat git. Effort rendah memangkas kedalamannya.",aria:{agent:"Runtime lead",model:"Model lead",effort:"Effort lead"},msg:{agent:"Runtime lead",model:"Model lead",effort:"Effort lead"}},defaults:s,codexVer:r,save:(g,S)=>He(t,i,g,S)})}),e.jsx(ke,{eyebrow:"portal",title:"Obrolan portal klien",desc:"Permukaan obrolan di portal klien: klien memilih Brainstorming (digali sampai jelas, keluarannya PRD draft untuk Anda review) atau Bertanya (dijawab langsung dari dokumen project). Jatah berlaku per project dan dihitung bulanan; brainstorming dan pertanyaan punya jatah masing-masing.",toggleTitle:"Aktifkan obrolan",toggleDesc:"Mati = klien hanya punya Pekerjaan & Help desk, persis seperti sebelumnya.",toggleAria:"Aktifkan obrolan portal",enabled:(a.portalChat??we).enabled,onToggle:g=>t.save({portalChat:{...a.portalChat??we,enabled:g}},"Obrolan portal"+(g?" · aktif":" · mati")),children:e.jsx(jn,{s:a,store:t,onToast:i})}),e.jsx(sn,{orchestration:a.orchestration,onChange:(g,S)=>{t.save({orchestration:g},S)}})]})}function jn({s:a,store:t,onToast:i}){const r=a.portalChat??we,d=(s,m)=>t.save({portalChat:{...r,...s}},m),h=$({value:r.model,delayMs:0,save:s=>d({model:s,...Je(s,r.effort)},"Model obrolan portal → "+s)}),l=$({value:r.effort,delayMs:0,save:s=>d({effort:s},"Effort obrolan portal → "+s)});return e.jsxs(e.Fragment,{children:[e.jsx(E,{title:"Jatah brainstorming",desc:"Berapa sesi brainstorming per project tiap bulan. 0 = tertutup.",children:e.jsx(fe,{label:"Jatah brainstorming",value:r.brainstormPerMonth,min:0,max:1e3,placeholder:"mis. 3",onToast:i,onCommit:s=>d({brainstormPerMonth:s},"Jatah brainstorming → "+s)})}),e.jsx(E,{title:"Jatah pertanyaan",desc:"Berapa sesi tanya-jawab per project tiap bulan. 0 = tertutup.",children:e.jsx(fe,{label:"Jatah pertanyaan",value:r.askPerMonth,min:0,max:1e4,placeholder:"mis. 30",onToast:i,onCommit:s=>d({askPerMonth:s},"Jatah pertanyaan → "+s)})}),e.jsx(E,{title:"Model",desc:"Mesin obrolan selalu Claude — gerbang tool yang menjaganya tak ada di runtime lain.",children:e.jsx(T,{size:"sm","aria-label":"Model obrolan portal",value:h.value,className:"hn-set-w-sm",options:Ve(h.value),onChange:s=>h.set(s.target.value)})}),e.jsx(E,{title:"Effort",children:e.jsx(T,{size:"sm","aria-label":"Effort obrolan portal",value:l.value,className:"hn-set-w-xs",options:qe(h.value),onChange:s=>l.set(s.target.value)})}),e.jsx(E,{title:"Batas waktu satu jawaban",last:!0,desc:"Detik. Lewat dari ini klien menerima kalimat 'coba lagi sebentar', bukan layar menggantung.",children:e.jsx(fe,{label:"Batas waktu obrolan portal",value:r.timeoutSec,min:10,max:900,placeholder:"mis. 120",onToast:i,onCommit:s=>d({timeoutSec:s},"Batas waktu obrolan → "+s)})})]})}const fn={name:"",url:"",events:["*"],enabled:!0,allowPrivate:!1},xn=Ge.map(a=>({entity:a.entity,label:a.label,types:ge.filter(t=>t.entity===a.entity).map(t=>t.type)})),ze=a=>a?new Date(a).toLocaleString("id-ID",{dateStyle:"short",timeStyle:"medium"}):"—";function vn({e:a}){return a.enabled?e.jsx(X,{tone:"ok",children:"aktif"}):a.disabledAt?e.jsx(X,{tone:"err",children:"dinonaktifkan otomatis"}):e.jsx(X,{children:"nonaktif"})}function yn({onToast:a,onOpenDocs:t}={}){const[i,r]=c.useState(null),[d,h]=c.useState(!1),[l,s]=c.useState(null),[m,j]=c.useState(null),[p,b]=c.useState(!1),[k,f]=c.useState({}),[g,S]=c.useState(null),[P,w]=c.useState([]),{confirm:D,dialog:O}=ie(),N=c.useCallback(async()=>{try{r((await y.listWebhooks()).endpoints),h(!1)}catch{h(!0)}},[]);c.useEffect(()=>{N()},[N]);const I=async o=>{S(o);try{w((await y.listWebhookDeliveries(o)).items)}catch{w([])}},z=async()=>{if(l){b(!0);try{if(l.id)await y.updateWebhook(l.id,{name:l.name,url:l.url,events:l.events,enabled:l.enabled,allowPrivate:l.allowPrivate}),a==null||a("Endpoint webhook diperbarui");else{const o=await y.createWebhook({name:l.name,url:l.url,events:l.events,enabled:l.enabled,allowPrivate:l.allowPrivate});j(o.secret??null),a==null||a("Endpoint webhook dibuat")}s(null),await N()}catch(o){a==null||a(K("menyimpan endpoint",o),"err")}finally{b(!1)}}},C=async o=>{b(!0);try{const A=await y.updateWebhook(o,{rotateSecret:!0});j(A.secret??null),await N()}catch(A){a==null||a(`Gagal merotasi secret: ${A.message}`,"err")}finally{b(!1)}},H=async(o,A)=>{try{await y.updateWebhook(o.id,{enabled:A}),await N()}catch(B){a==null||a(K("mengubah status endpoint",B),"err")}},L=async o=>{b(!0);try{const A=await y.testWebhook(o);f(B=>({...B,[o]:A})),await N()}catch(A){f(B=>({...B,[o]:{ok:!1,httpStatus:null,durationMs:0,error:A.message}}))}finally{b(!1)}},Q=async o=>{try{await D({title:`Hapus endpoint "${o.name}"?`,message:"Endpoint ini tak lagi menerima peristiwa dari hanoman.",impact:["Riwayat pengiriman endpoint ini ikut dihapus.","Tindakan ini tak bisa dibatalkan."],confirmLabel:"Hapus endpoint",tone:"danger",icon:"trash-2",run:()=>y.deleteWebhook(o.id)})&&(a==null||a("Endpoint webhook dihapus"),await N())}catch(A){a==null||a(K("menghapus endpoint",A),"err")}},q=async o=>{try{await y.retryWebhookDelivery(o),g&&await I(g),await N()}catch(A){a==null||a(`Gagal antre ulang: ${A.message}`,"err")}},Y=(o,A)=>s(B=>B&&{...B,events:A?[...new Set([...B.events.filter(u=>u!=="*"),...o])]:B.events.filter(u=>u!=="*"&&!o.includes(u))}),U=(l==null?void 0:l.events.includes("*"))??!1;return e.jsxs(e.Fragment,{children:[e.jsxs(M,{eyebrow:"integrasi",title:"Webhook keluar",children:[e.jsxs("div",{className:"hn-wh-muted hn-wh-mb12",children:["hanoman mengirim ",e.jsx("b",{children:"HTTP POST"})," bertanda tangan ke endpoint yang Anda daftarkan setiap kali sesuatu berubah — backlog dibuat atau berpindah stage, sesi mulai dan selesai, putusan lead terbit, tiket masuk, notifikasi. Pengiriman berjalan di antrean: penerima yang lambat atau mati ",e.jsx("b",{children:"tidak"})," memperlambat hanoman."]}),e.jsxs("div",{className:"hn-wh-actions",children:[e.jsxs(x,{size:"sm",onClick:()=>{s({...fn}),j(null)},children:[e.jsx(le,{name:"plus",size:14})," Tambah endpoint"]}),t&&e.jsxs(x,{size:"sm",variant:"ghost",onClick:t,children:[e.jsx(le,{name:"book-open",size:14})," Dokumentasi webhook"]})]}),d?e.jsx(W,{kind:"error",compact:!0,title:"Gagal memuat endpoint webhook",hint:"Coba muat ulang.",action:()=>void N(),actionLabel:"Coba lagi"}):i===null?e.jsx("div",{className:"hn-wh-muted",children:"Memuat…"}):i.length===0?e.jsx(W,{kind:"empty",compact:!0,title:"Belum ada endpoint webhook",hint:"Daftarkan URL penerima pertama untuk mulai berlangganan peristiwa hanoman."}):e.jsx("div",{className:"hn-wh-col-10",children:i.map(o=>e.jsxs("div",{"data-testid":`webhook-${o.id}`,className:"hn-wh-endpoint",children:[e.jsxs("div",{className:"hn-wh-endpoint-head",children:[e.jsx("div",{className:"hn-wh-name",children:o.name}),e.jsx(vn,{e:o}),o.pending>0?e.jsxs(X,{children:[o.pending," mengantre"]}):null,e.jsxs("div",{className:"hn-wh-endpoint-actions",children:[e.jsx(J,{checked:o.enabled,"aria-label":`Aktifkan ${o.name}`,onChange:A=>void H(o,A)}),e.jsx(x,{size:"sm",variant:"ghost",disabled:p,onClick:()=>void L(o.id),children:"Test"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>void I(o.id),children:"Riwayat"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>{j(null),s({id:o.id,name:o.name,url:o.url,events:o.events,enabled:o.enabled,allowPrivate:o.allowPrivate})},children:"Ubah"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>void Q(o),children:"Hapus"})]})]}),e.jsx("div",{className:"hn-wh-url",children:o.url}),e.jsxs("div",{className:"hn-wh-muted hn-wh-mt6",children:["Peristiwa: ",e.jsx("code",{children:o.events.join(", ")})," · secret …",o.secretHint," ·"," ","sukses terakhir ",ze(o.lastSuccessAt),o.failureStreak>0?` · ${o.failureStreak} gagal beruntun`:""]}),o.disabledReason?e.jsx("div",{className:"hn-wh-muted hn-wh-mt6 hn-wh-err",children:o.disabledReason}):null,k[o.id]?e.jsx("div",{className:"hn-wh-muted hn-wh-mt6",children:k[o.id].ok?`Test berhasil — HTTP ${k[o.id].httpStatus} · ${k[o.id].durationMs} ms`:`Test gagal — ${k[o.id].error}`}):null]},o.id))})]}),m?e.jsxs(M,{eyebrow:"secret",title:"Salin sekarang — secret tak ditampilkan lagi",children:[e.jsx(te,{tone:"brass",children:e.jsx("div",{className:"hn-wh-secret",children:m})}),e.jsxs("div",{className:"hn-wh-row hn-wh-mt10",children:[e.jsx(x,{size:"sm",onClick:()=>{var o;return void((o=navigator.clipboard)==null?void 0:o.writeText(m))},children:"Salin secret"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>j(null),children:"Tutup"})]})]}):null,l?e.jsx(M,{eyebrow:l.id?"ubah":"tambah",title:l.id?"Ubah endpoint":"Endpoint baru",children:e.jsxs("div",{className:"hn-wh-col-12",children:[e.jsx(Z,{label:"Nama",children:e.jsx(V,{value:l.name,placeholder:"mis. Dashboard internal",onChange:o=>s({...l,name:o.target.value})})}),e.jsx(Z,{label:"URL tujuan",children:e.jsx(V,{value:l.url,placeholder:"https://contoh.id/hanoman-webhook",onChange:o=>s({...l,url:o.target.value})})}),e.jsxs("div",{children:[e.jsx("div",{className:"hn-wh-label",children:"Peristiwa yang dikirim"}),e.jsx(oe,{checked:U,label:"Semua peristiwa",onChange:o=>s({...l,events:o?["*"]:[]})}),U?null:e.jsxs("div",{className:"hn-wh-tree",children:[xn.map(o=>e.jsxs("div",{children:[e.jsx(oe,{checked:o.types.every(A=>l.events.includes(A)),label:o.label,onChange:A=>Y(o.types,A)}),e.jsx("div",{className:"hn-wh-family-types",children:o.types.map(A=>e.jsx(oe,{checked:l.events.includes(A),label:A,onChange:B=>s({...l,events:B?[...new Set([...l.events.filter(u=>u!=="*"),A])]:l.events.filter(u=>u!==A&&u!=="*")})},A))})]},o.entity)),e.jsxs("div",{className:"hn-wh-muted",children:[e.jsx("code",{children:Ha})," selalu terkirim saat tombol Test ditekan, apa pun langganannya."]})]})]}),e.jsx(oe,{checked:l.allowPrivate,label:"Izinkan alamat internal / loopback",onChange:o=>s({...l,allowPrivate:o})}),e.jsx("div",{className:"hn-wh-muted",children:"Biarkan mati kecuali penerima memang berjalan di mesin/jaringan yang sama. Menyalakannya membuka jalan ke layanan internal yang tak pernah dimaksudkan terekspos."}),e.jsx(oe,{checked:l.enabled,label:"Aktif",onChange:o=>s({...l,enabled:o})}),e.jsxs("div",{className:"hn-wh-row",children:[e.jsx(x,{size:"sm",disabled:p||!l.name||!l.url||l.events.length===0,onClick:()=>void z(),children:"Simpan"}),e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>s(null),children:"Batal"}),l.id?e.jsx(x,{size:"sm",variant:"ghost",disabled:p,onClick:()=>void C(l.id),children:"Rotasi secret"}):null]})]})}):null,g?e.jsxs(M,{eyebrow:"riwayat",title:"Riwayat pengiriman",children:[e.jsx("div",{className:"hn-wh-history-head",children:e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>S(null),children:"Tutup riwayat"})}),P.length===0?e.jsx("div",{className:"hn-wh-muted",children:"Belum ada pengiriman."}):e.jsx("div",{className:"hn-local-overflow",children:e.jsxs("table",{className:"hn-wh-table hn-wh-table--full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"hn-wh-thead",children:[e.jsx("th",{className:"hn-wh-cell",children:"Waktu"}),e.jsx("th",{className:"hn-wh-cell",children:"Jenis"}),e.jsx("th",{className:"hn-wh-cell",children:"Status"}),e.jsx("th",{className:"hn-wh-cell",children:"HTTP"}),e.jsx("th",{className:"hn-wh-cell",children:"Percobaan"}),e.jsx("th",{className:"hn-wh-cell",children:"Galat"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:P.map(o=>e.jsxs("tr",{className:"hn-wh-tr",children:[e.jsx("td",{className:"hn-wh-cell hn-wh-cell--nowrap",children:ze(o.createdAt)}),e.jsx("td",{className:"hn-wh-cell hn-wh-cell--mono12",children:o.eventType}),e.jsx("td",{className:"hn-wh-cell",children:o.status}),e.jsx("td",{className:"hn-wh-cell",children:o.httpStatus??"—"}),e.jsx("td",{className:"hn-wh-cell",children:`${o.attempt} / ${o.maxAttempts}`}),e.jsx("td",{className:"hn-wh-cell hn-wh-cell--muted",children:o.error??"—"}),e.jsx("td",{className:"hn-wh-cell",children:o.status==="failed"||o.status==="dropped"?e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>void q(o.id),children:"Antre ulang"}):null})]},o.id))})]})})]}):null,O]})}function ve({text:a,label:t="Salin"}){const[i,r]=c.useState(!1);return e.jsxs("div",{className:"hn-wh-copy",children:[e.jsx("pre",{className:"hn-wh-code",children:a}),e.jsx("div",{className:"hn-wh-mt6",children:e.jsx(x,{size:"sm",variant:"ghost",onClick:()=>{var d;(d=navigator.clipboard)==null||d.writeText(a),r(!0),setTimeout(()=>r(!1),1500)},children:i?"Tersalin":t})})]})}const wn=`// Node.js (Express) — verifikasi tanda tangan webhook hanoman
2
2
  import express from "express";
3
3
  import { createHmac, timingSafeEqual } from "node:crypto";
4
4
 
@@ -1 +1 @@
1
- import{T as ra,a as Pa,b as Ba,j as a,c as Se,O as oa,P as me,I as q,d as ca,M as we,e as $,f as Y,g as B,H as Aa,B as U,h as D,i as Ce,k as He,E as Ra,s as _a,C as Ua,m as W,n as Ze,o as ke,p as Fa,q as X,r as Ye,t as Ka,v as za,w as Ga,x as Ha,y as Za,z as Ya,A as Va,D as xe,G as Wa}from"./index-CbX7iwxN.js";import{R as d}from"./react-DfGhg7ZW.js";import{L as qa}from"./live-CNp86nGW.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";const Ja=Pa,Z=ra.map(e=>({key:e,label:Ja[e]})),Qa=()=>Object.fromEntries(ra.map(e=>[e,[]])),Ne=(e,t)=>e!==t,da=e=>e.length===0?0:e.reduce((t,n)=>n.order>t?n.order:t,-1/0)+1;function Xa(e,t,n,l){if(!Ne(n,l))return null;const r=e[n].find(f=>f.id===t);if(!r)return null;const o={status:l,order:da(e[l])},u={...e};return u[n]=e[n].filter(f=>f.id!==t),u[l]=[...e[l],{...r,...o}],{board:u,patch:o}}function ye(e,t){const n={...e};return n[t.status]=e[t.status].map(l=>l.id===t.id?t:l),n}const Ve=e=>e?e.slice(0,10):"",We=e=>/^\d{4}-\d{2}-\d{2}$/.test(e)?`${e}T12:00:00.000Z`:null,J=864e5,se=e=>Math.floor(e/J)*J,qe=e=>{if(!e)return null;const t=new Date(e).getTime();return Number.isFinite(t)?t:null};function ee(e){const t=qe(e.startDate),n=qe(e.dueDate);if(t===null&&n===null)return null;const l=t??n,r=n??t;return{start:se(Math.min(l,r)),end:se(Math.max(l,r))+J,invalid:r<l}}const et=new Intl.DateTimeFormat("id-ID",{day:"numeric",month:"short",timeZone:"UTC"}),Je=e=>e?et.format(new Date(e)):null;function ue(e){const t=Je(e.startDate),n=Je(e.dueDate);return t&&n?`${t} → ${n}`:n?`→ ${n}`:t}const Qe=["day","week","month"],ua={day:{cell:34,minTicks:14},week:{cell:56,minTicks:8},month:{cell:84,minTicks:6}},at=e=>ua[e].cell,tt=120,nt=(e,t)=>{const n=se(e);if(t==="day")return n;if(t==="week")return n-(new Date(n).getUTCDay()+6)%7*J;const l=new Date(n);return Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),1)},st=(e,t)=>{if(t==="day")return e+J;if(t==="week")return e+7*J;const n=new Date(e);return Date.UTC(n.getUTCFullYear(),n.getUTCMonth()+1,1)},lt=new Intl.DateTimeFormat("id-ID",{day:"numeric",timeZone:"UTC"}),Xe=new Intl.DateTimeFormat("id-ID",{day:"numeric",month:"short",timeZone:"UTC"}),it=new Intl.DateTimeFormat("id-ID",{month:"short",timeZone:"UTC"}),rt=new Intl.DateTimeFormat("id-ID",{month:"short",year:"2-digit",timeZone:"UTC"}),ot=(e,t)=>{const n=new Date(e);return t==="day"?n.getUTCDate()===1:t==="week"?n.getUTCDate()<=7:n.getUTCMonth()===0},ct=(e,t,n)=>{const l=new Date(e);return t==="day"?(n?Xe:lt).format(l):t==="week"?Xe.format(l):(n?rt:it).format(l)};function ma(e,t,n){const l=se(n);let r=l,o=l+J;for(const b of e)b.start<r&&(r=b.start),b.end>o&&(o=b.end);const u=nt(r,t),{minTicks:f}=ua[t],p=[];let i=u;for(;p.length<tt&&(i<o||p.length<f);){const b=ot(i,t);p.push({start:i,label:ct(i,t,b),major:b}),i=st(i,t)}return{from:u,to:i,zoom:t,ticks:p}}function ha(e,t){const n=t.to-t.from;if(n<=0||e.end<=t.from||e.start>=t.to)return null;const l=Math.max(e.start,t.from),r=Math.min(e.end,t.to);return{left:(l-t.from)/n*100,width:(r-l)/n*100,clippedStart:e.start<t.from,clippedEnd:e.end>t.to,invalid:e.invalid}}function Ie(e,t){const n=ee(e);return n?ha(n,t):null}function dt(e){let t=1/0,n=-1/0,l=!1;for(const r of e){const o=ee(r);o&&(o.start<t&&(t=o.start),o.end>n&&(n=o.end),o.invalid&&(l=!0))}return t===1/0?null:{start:t,end:n,invalid:l}}function ut(e,t){const n=se(t);return n<e.from||n>=e.to?null:(n-e.from)/(e.to-e.from)*100}function mt(e,t){const n=[],l=[],r=[];for(const o of e){const u=ee(o);if(!u){l.push(o);continue}const f=Ie(o,t);if(!f){r.push(o);continue}n.push({task:o,geometry:f,start:u.start})}return n.sort((o,u)=>o.start-u.start||o.task.title.localeCompare(u.task.title,"id")||o.task.id.localeCompare(u.task.id)),{rows:n.map(({task:o,geometry:u})=>({task:o,geometry:u})),unscheduled:l,outside:r}}const ea=(e,t)=>e.title.localeCompare(t.title,"id")||e.id.localeCompare(t.id);function ht(e,t,n){const l=Symbol("no-project"),r=new Map;for(const p of e){const i=p.projectId??l,b=r.get(i);b?b.tasks.push(p):r.set(i,{projectId:p.projectId,tasks:[p]})}const o=[...r.values()].map(({projectId:p,tasks:i})=>{const b=dt(i),m=[],k=[];for(const S of i){const j=ee(S);j?m.push({task:S,start:j.start}):k.push(S)}return m.sort((S,j)=>S.start-j.start||ea(S.task,j.task)),k.sort(ea),{projectId:p,span:b,geometry:b?ha(b,t):null,tasks:[...m.map(S=>S.task),...k]}}),u=p=>p.geometry?0:p.span?1:2,f=p=>p.projectId===null?[1,""]:[0,p.projectId];return o.sort((p,i)=>{const[b,m]=f(p),[k,S]=f(i);return u(p)-u(i)||(p.span&&i.span?p.span.start-i.span.start:0)||n(p.projectId).localeCompare(n(i.projectId),"id")||b-k||m.localeCompare(S)}),o}const pt={tinggi:"high",sedang:"mid",rendah:"low"};function gt({priority:e}){const t=pt[e]??"mid",n=me[e]??e;return a.jsx("span",{className:`hn-tm-prio hn-tm-prio-${t}`,title:`Prioritas ${n}`,children:a.jsxs("span",{className:"hn-sr-only",children:["Prioritas ",n]})})}function bt({name:e}){if(!e)return a.jsx("span",{className:"hn-tm-avatar hn-tm-avatar-empty","aria-hidden":"true",children:a.jsx(q,{name:"user",size:12})});const t=e.split(/\s+/).filter(Boolean).slice(0,2).map(n=>n[0].toUpperCase()).join("");return a.jsx("span",{className:"hn-tm-avatar","aria-hidden":"true",children:t||"?"})}function ft(e,t,n){const l=[...Z.filter(r=>r.key!==e.status).map(r=>({key:`move-${r.key}`,label:`Pindah ke ${r.label}`,onSelect:()=>n.onMove(e,r.key)})),...t.map(r=>({key:`assign-${r.id}`,label:`Tugaskan ke ${r.name}`,disabled:e.memberId===r.id,onSelect:()=>n.onAssign(e,r.id)})),{key:"assign-none",label:"Kosongkan penugasan",disabled:!e.memberId,onSelect:()=>n.onAssign(e,null)}];if(e.specId){if(e.spec&&n.onOpenSpec){const r=e.specId;l.push({key:"open-spec",label:`Buka ${e.spec.id} di Backlog`,onSelect:()=>{var o;return(o=n.onOpenSpec)==null?void 0:o.call(n,r)}})}l.push({key:"unlink",label:e.spec?"Lepas tautan":"Lepas tautan (spec tak ditemukan)",onSelect:()=>n.onUnlink(e)})}else l.push({key:"escalate",label:"Kirim ke Backlog",onSelect:()=>n.onEscalate(e)});return l}function jt({task:e,members:t,projectName:n,dragging:l,onDragStart:r,onDragEnd:o,onOpen:u,onMove:f,onAssign:p,onEscalate:i,onUnlink:b,onOpenSpec:m}){var C;const k=((C=t.find(h=>h.id===e.memberId))==null?void 0:C.name)??null,S=ft(e,t,{onMove:f,onAssign:p,onEscalate:i,onUnlink:b,onOpenSpec:m}),j=e.projectId===null?"tanpa project":n??"project tak dikenal";return a.jsxs("div",{draggable:!0,"data-testid":`team-card-${e.id}`,className:"hn-tm-card","data-dragging":l||void 0,title:`Project: ${j}`,onDragStart:h=>{h.dataTransfer.effectAllowed="move",h.dataTransfer.setData("text/plain",e.id),r()},onDragEnd:o,children:[a.jsxs("div",{className:"hn-tm-card-head",children:[a.jsx(gt,{priority:e.priority}),a.jsx("button",{type:"button",className:"hn-tm-title",onClick:()=>u(e),children:e.title})]}),a.jsx("span",{className:"hn-tm-project","data-empty":e.projectId===null||void 0,children:j}),a.jsxs("div",{className:"hn-tm-card-foot",children:[a.jsxs("span",{className:"hn-tm-assignee-wrap",children:[a.jsx(bt,{name:k}),a.jsx("span",{className:"hn-tm-assignee",children:k??"belum ditugaskan"})]}),a.jsx(oa,{label:`Ubah tugas: ${e.title}`,icon:"ellipsis",items:S})]})]})}function kt({board:e,totals:t,columns:n,members:l,projects:r=[],onMove:o,onAssign:u,onOpen:f,onEscalate:p,onUnlink:i,onOpenSpec:b}){var T;const[m,k]=d.useState(null),[S,j]=d.useState(null),C=Ba(),[h,N]=d.useState(((T=n[0])==null?void 0:T.key)??"backlog"),M=d.useMemo(()=>{const c=new Map(r.map(y=>[y.id,y.name]));return y=>y===null?null:c.get(y)??null},[r]),A=c=>{m&&Ne(m.from,c)&&o(m.task,c),k(null),j(null)},g=(c,y)=>a.jsx(jt,{task:c,members:l,projectName:M(c.projectId),dragging:(m==null?void 0:m.task.id)===c.id,onDragStart:()=>k({task:c,from:y}),onDragEnd:()=>{k(null),j(null)},onOpen:f,onMove:o,onAssign:u,onEscalate:p,onUnlink:i,onOpenSpec:b},c.id);if(C==="mobile"){const c=n.find(I=>I.key===h)??n[0];if(!c)return null;const y=e[c.key],L=Math.max(0,(t[c.key]??0)-y.length);return a.jsxs("div",{"data-testid":"team-board","data-layout":"mobile",className:"hn-tm-mobile",children:[a.jsx(Se,{variant:"pill","aria-label":"Kolom papan tim",value:c.key,onChange:I=>N(I),tabs:n.map(I=>({value:I.key,label:`${I.label} · ${e[I.key].length}`}))}),a.jsxs("div",{"data-testid":`team-col-${c.key}`,className:"hn-tm-col-stack",children:[y.map(I=>g(I,c.key)),y.length===0&&a.jsxs("div",{className:"hn-tm-empty-col",children:["Tak ada tugas di ",c.label,"."]}),L>0&&a.jsxs("div",{className:"hn-tm-hidden-note",children:["menampilkan ",y.length," dari ",t[c.key]," — persempit penyaring"]})]})]})}return a.jsx("div",{"data-testid":"team-board",className:"hn-board-local-overflow hn-tm-board",children:n.map(c=>{const y=e[c.key],L=!!m&&Ne(m.from,c.key),I=L&&S===c.key,K=Math.max(0,(t[c.key]??0)-y.length);return a.jsxs("div",{"data-testid":`team-col-${c.key}`,className:"hn-tm-col","data-active":L||void 0,"data-hot":I||void 0,"data-dimmed":m&&!L||void 0,onDragOver:v=>{L&&(v.preventDefault(),v.dataTransfer.dropEffect="move",j(c.key))},onDragLeave:()=>j(v=>v===c.key?null:v),onDrop:v=>{v.preventDefault(),A(c.key)},children:[a.jsxs("div",{className:"hn-tm-col-head",children:[a.jsx("span",{className:"hn-eyebrow",children:c.label}),a.jsx("span",{className:"hn-tm-col-count",children:y.length})]}),a.jsx("div",{className:"hn-tm-col-body",children:y.map(v=>g(v,c.key))}),K>0&&a.jsxs("div",{className:"hn-tm-hidden-note",children:["menampilkan ",y.length," dari ",t[c.key]," — persempit penyaring"]})]},c.key)})})}const ve=232,xt={brass:"var(--brass-500)",err:"var(--status-err)",muted:"var(--border-strong)",envelope:"var(--border-hair)"},Te=e=>e;function yt({spec:e}){const t=e.geometry,n=xt[e.tone],l=!!e.onClick,r={"data-testid":`timeline-bar-${e.key}`,"data-tone":e.tone,"data-invalid":t.invalid?"true":"false","data-clipped-start":t.clippedStart?"true":"false","data-clipped-end":t.clippedEnd?"true":"false",title:e.title,"aria-label":e.title,onClick:e.onClick,className:"hn-tl-bar",style:Te({"--tl-left":`${t.left}%`,"--tl-width":`${t.width}%`})},o=a.jsxs(a.Fragment,{children:[t.invalid&&a.jsx(q,{name:"triangle-alert",size:11,color:n}),t.clippedStart&&a.jsx(q,{name:"chevron-left",size:11,color:n}),a.jsx("span",{className:"hn-grow"}),t.clippedEnd&&a.jsx(q,{name:"chevron-right",size:11,color:n})]});return l?a.jsx("button",{type:"button",...r,children:o}):a.jsx("div",{role:"img",...r,children:o})}function pa({envelope:e=!1}){const t=n=>a.jsx("span",{"aria-hidden":"true",className:"hn-tl-swatch","data-tone":n});return a.jsxs("ul",{"aria-label":"Legenda linimasa",className:"hn-tl-legend",children:[a.jsxs("li",{className:"hn-tl-legend-item",children:[t("brass"),"Rencana"]}),a.jsxs("li",{className:"hn-tl-legend-item",children:[t("muted"),"Selesai"]}),a.jsxs("li",{className:"hn-tl-legend-item",children:[t("err"),a.jsx(q,{name:"triangle-alert",size:11,color:"var(--status-err)"}),"Tenggat mendahului mulai"]}),e&&a.jsxs("li",{className:"hn-tl-legend-item",children:[t("envelope"),"Rentang project (buka lewat namanya)"]})]})}function ga({window:e,rows:t,today:n,emptyHint:l,testId:r,labelHead:o}){const u=at(e.zoom),f=e.ticks.length*u,p=ut(e,n);return a.jsx("div",{"data-testid":r??"team-timeline",className:"hn-timeline-scroll hn-tl-scroll",children:a.jsxs("div",{"data-testid":"timeline-canvas",className:"hn-tl",style:Te({"--tl-label-w":`${ve}px`,"--tl-cell":`${u}px`,"--tl-ticks":String(e.ticks.length),"--tl-track-w":`${f}px`,"--tl-canvas-w":`${ve+f}px`}),children:[a.jsxs("div",{className:"hn-tl-head",children:[a.jsx("div",{className:"hn-tl-label",children:a.jsx("span",{className:"hn-eyebrow",children:o??"Tugas"})}),a.jsx("div",{className:"hn-tl-ticks",children:e.ticks.map(i=>a.jsx("div",{"data-testid":"timeline-tick","data-major":i.major?"true":"false",className:"hn-tl-tick",children:i.label},i.start))})]}),t.length===0?a.jsx("div",{"data-testid":"timeline-empty",className:"hn-tl-empty",children:l??"Tak ada yang bisa dihamparkan di jendela ini."}):t.map(i=>a.jsxs("div",{"data-testid":`timeline-row-${i.key}`,className:"hn-tl-row",children:[a.jsxs("div",{className:"hn-tl-label",children:[a.jsx("div",{className:"hn-tl-label-text",children:i.label}),i.meta&&a.jsx("div",{className:"hn-tl-label-meta",children:i.meta})]}),a.jsx("div",{className:"hn-tl-track",children:i.bars.map(b=>a.jsx(yt,{spec:b},b.key))})]},i.key)),p!==null&&a.jsx("div",{"data-testid":"timeline-today","aria-hidden":"true",className:"hn-tl-today",style:Te({"--tl-today-x":`${ve+p/100*f}px`})})]})})}function aa({testId:e,icon:t,title:n,hint:l,tasks:r,onOpen:o}){return r.length===0?null:a.jsxs("div",{"data-testid":e,className:"hn-tl-aside",children:[a.jsxs("div",{className:"hn-tl-aside-head",children:[a.jsx(q,{name:t,size:13,color:"var(--text-subtle)"}),a.jsxs("span",{className:"hn-eyebrow",children:[n," · ",r.length]}),l&&a.jsx("span",{className:"hn-tl-aside-hint",children:l})]}),a.jsx("div",{className:"hn-tl-aside-list",children:r.map(u=>a.jsx("button",{type:"button",onClick:()=>o(u),className:"hn-tl-chip",children:u.title},u.id))})]})}function vt({tasks:e,members:t,zoom:n,today:l,hidden:r,onOpen:o}){const u=d.useMemo(()=>{const m=e.map(ee).filter(k=>k!==null);return ma(m,n,l)},[e,n,l]),{rows:f,unscheduled:p,outside:i}=d.useMemo(()=>mt(e,u),[e,u]),b=d.useMemo(()=>f.map(({task:m,geometry:k})=>{var h;const S=((h=t.find(N=>N.id===m.memberId))==null?void 0:h.name)??"belum ditugaskan",j=ue(m),C=[k.invalid?"tenggat mendahului mulai":null,k.clippedStart||k.clippedEnd?"melewati tepi jendela":null].filter(Boolean);return{key:m.id,label:m.title,meta:j?`${S} · ${j}`:S,bars:[{key:m.id,geometry:k,tone:k.invalid?"err":m.status==="done"?"muted":"brass",title:[m.title,j,...C].filter(Boolean).join(" · "),onClick:()=>o(m)}]}}),[f,t,o]);return a.jsxs(a.Fragment,{children:[a.jsx(pa,{}),a.jsx(ga,{window:u,rows:b,today:l,emptyHint:"Belum ada tugas bertanggal — isi mulai atau tenggat di kartunya."}),r>0&&a.jsxs("div",{"data-testid":"timeline-truncated",className:"hn-tl-note",children:[r," tugas tak termuat karena plafon 200 per kolom — persempit penyaring"]}),a.jsx(aa,{testId:"timeline-unscheduled",icon:"calendar-off",title:"Belum dijadwalkan",tasks:p,onOpen:o}),a.jsx(aa,{testId:"timeline-outside",icon:"chevrons-left-right",title:"Di luar jendela",hint:"pilih zoom yang lebih lebar",tasks:i,onOpen:o})]})}const St="__none__",ta=(e,t)=>t.invalid?"err":e.status==="done"?"muted":"brass",na=(e,t,n)=>[e.title,n,t.invalid?"tenggat mendahului mulai":null,t.clippedStart||t.clippedEnd?"melewati tepi jendela":null].filter(Boolean).join(" · ");function Ct({testId:e,open:t,name:n,count:l,onClick:r}){return a.jsxs("button",{type:"button",onClick:r,"data-testid":e,"aria-expanded":t,className:"hn-tl-expand",children:[a.jsx(q,{name:t?"chevron-down":"chevron-right",size:12,color:"var(--text-subtle)"}),a.jsx("span",{className:"hn-tl-expand-name",children:n}),a.jsx("span",{className:"hn-tl-expand-count",children:l})]})}function Nt({tasks:e,projects:t,members:n,zoom:l,today:r,hidden:o,expanded:u,onToggle:f,onOpen:p}){const i=d.useMemo(()=>{const j=e.map(ee).filter(C=>C!==null);return ma(j,l,r)},[e,l,r]),b=d.useCallback(j=>{var C;return j===null?"Tanpa project":((C=t.find(h=>h.id===j))==null?void 0:C.name)??j},[t]),m=d.useMemo(()=>ht(e,i,b),[e,i,b]),k=d.useMemo(()=>new Set(u),[u]),S=d.useMemo(()=>{var C;const j=[];for(const h of m){const N=h.projectId??St,M=k.has(N),A=b(h.projectId),g=h.geometry?ue({startDate:new Date(h.span.start).toISOString(),dueDate:new Date(h.span.end-1).toISOString()}):h.span?"di luar jendela · pilih zoom yang lebih lebar":"belum dijadwalkan",T=[];if(h.geometry){T.push({key:`span:${N}`,geometry:h.geometry,tone:h.geometry.invalid?"err":"envelope",title:`${A} · ${g??""}`.trim()});for(const c of h.tasks){const y=Ie(c,i);y&&T.push({key:`seg:${c.id}`,geometry:y,tone:ta(c,y),title:na(c,y,ue(c)),onClick:()=>p(c)})}}if(j.push({key:`p:${N}`,meta:g,bars:T,label:a.jsx(Ct,{testId:`expand-${N}`,open:M,name:A,count:h.tasks.length,onClick:()=>f(N)})}),!!M)for(const c of h.tasks){const y=Ie(c,i),L=((C=n.find(K=>K.id===c.memberId))==null?void 0:C.name)??"belum ditugaskan",I=ue(c);j.push({key:`t:${c.id}`,label:a.jsx("span",{className:"hn-tl-child",children:c.title}),meta:I?`${L} · ${I}`:L,bars:y?[{key:`t:${c.id}`,geometry:y,tone:ta(c,y),title:na(c,y,I),onClick:()=>p(c)}]:[]})}}return j},[m,k,b,i,n,f,p]);return a.jsxs(a.Fragment,{children:[a.jsx(pa,{envelope:!0}),a.jsx(ga,{window:i,rows:S,today:r,testId:"team-projects",labelHead:"Project",emptyHint:"Belum ada project bertanggal — isi mulai atau tenggat di kartunya."}),o>0&&a.jsxs("div",{"data-testid":"projects-truncated",className:"hn-tl-note",children:[o," tugas tak termuat karena plafon 200 per kolom — amplop project bisa lebih pendek dari rentang sebenarnya; persempit kolom, anggota, atau pencarian"]})]})}const It=Object.keys(me).map(e=>({value:e,label:me[e]})),sa=(e,t)=>({title:(e==null?void 0:e.title)??"",detail:(e==null?void 0:e.detail)??"",projectId:e?e.projectId??"":t??"",status:(e==null?void 0:e.status)??"backlog",priority:e&&e.priority in me?e.priority:"sedang",memberId:(e==null?void 0:e.memberId)??"",startDate:Ve((e==null?void 0:e.startDate)??null),dueDate:Ve((e==null?void 0:e.dueDate)??null)});function Tt({open:e,task:t,projects:n,members:l,defaultProjectId:r,orderFor:o,onClose:u,onSaved:f,onToast:p}){const[i,b]=d.useState(()=>sa(t,r)),[m,k]=d.useState(!1),{confirm:S,dialog:j}=ca(),C=`${e?"1":"0"}:${(t==null?void 0:t.id)??""}`,h=d.useRef(C);if(h.current!==C&&(h.current=C,e&&b(sa(t,r))),!e)return null;const N=g=>b(T=>({...T,...g}));async function M(){if(!i.title.trim()){p("Judul tugas wajib diisi","err","x-circle");return}k(!0);const g=!t||t.status!==i.status,T={title:i.title.trim(),detail:i.detail.trim()||null,projectId:i.projectId||null,status:i.status,priority:i.priority,memberId:i.memberId||null,startDate:We(i.startDate),dueDate:We(i.dueDate),...g?{order:o(i.status)}:{}};try{t?await D.patchTask(t.id,T):await D.createTask(T),p(t?"Tugas diperbarui":"Tugas dibuat","ok","check"),f(),u()}catch(c){p(Ce("menyimpan tugas",c),"err","x-circle")}finally{k(!1)}}async function A(){if(t){try{if(!await S({title:`Hapus "${t.title}"?`,impact:["Kartu ini hilang dari papan di semua device yang tersinkron."],confirmLabel:"Hapus tugas",tone:"danger",icon:"trash-2",run:async()=>{k(!0);try{await D.deleteTask(t.id)}finally{k(!1)}}}))return}catch(g){p(Ce("menghapus tugas",g),"err","x-circle");return}p("Tugas dihapus","ok","trash-2"),f(),u()}}return a.jsxs(a.Fragment,{children:[a.jsxs(we,{open:e,onClose:m?void 0:u,icon:"clipboard-list",eyebrow:"Papan tim",title:t?"Ubah tugas":"Tugas baru",footer:a.jsxs("div",{style:{display:"flex",gap:8,width:"100%",alignItems:"center"},children:[t&&a.jsx(U,{variant:"ghost",leftIcon:"trash-2",onClick:A,disabled:m,children:"Hapus"}),a.jsx("span",{style:{flex:1}}),a.jsx(U,{variant:"secondary",onClick:u,disabled:m,children:"Batal"}),a.jsx(U,{onClick:M,loading:m,children:t?"Simpan":"Buat tugas"})]}),children:[a.jsx($,{label:"Judul",children:a.jsx(Y,{value:i.title,"aria-label":"Judul tugas",placeholder:"mis. Rapikan halaman harga",onChange:g=>N({title:g.target.value}),style:{width:"100%"}})}),a.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[a.jsx($,{label:"Project",children:a.jsx(B,{value:i.projectId,"aria-label":"Project tugas",onChange:g=>N({projectId:g.target.value}),options:[{value:"",label:"Tanpa project"},...n.map(g=>({value:g.id,label:g.name}))]})}),a.jsx($,{label:"Kolom",children:a.jsx(B,{value:i.status,"aria-label":"Kolom tugas",onChange:g=>N({status:g.target.value}),options:Z.map(g=>({value:g.key,label:g.label}))})}),a.jsx($,{label:"Prioritas",children:a.jsx(B,{value:i.priority,"aria-label":"Prioritas tugas",onChange:g=>N({priority:g.target.value}),options:It})})]}),a.jsx($,{label:"Ditugaskan ke",children:a.jsx(B,{value:i.memberId,"aria-label":"Anggota tugas",onChange:g=>N({memberId:g.target.value}),options:[{value:"",label:"Belum ditugaskan"},...l.map(g=>({value:g.id,label:g.role?`${g.name} · ${g.role}`:g.name}))],style:{width:"100%"}})}),a.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[a.jsx($,{label:"Mulai",children:a.jsx(Y,{type:"date",value:i.startDate,"aria-label":"Tanggal mulai",onChange:g=>N({startDate:g.target.value})})}),a.jsx($,{label:"Tenggat",children:a.jsx(Y,{type:"date",value:i.dueDate,"aria-label":"Tanggal tenggat",onChange:g=>N({dueDate:g.target.value})})})]}),a.jsx($,{label:"Detail",hint:"Opsional — konteks yang tak muat di judul.",children:a.jsx(Aa,{value:i.detail,"aria-label":"Detail tugas",rows:4,placeholder:"mis. tunggu aset dari klien, deadline ikut jadwal kampanye",onChange:g=>N({detail:g.target.value})})})]}),j]})}const wt=Ra.map(e=>({value:e,label:_a(e).label}));function Dt({task:e,projects:t,onClose:n,onDone:l,onToast:r}){const[o,u]=d.useState("brief"),[f,p]=d.useState(()=>He.some(h=>h.value===e.priority)?e.priority:"sedang"),[i,b]=d.useState(""),[m,k]=d.useState(!1),S=e.projectId===null,j=e.projectId??i;async function C(){if(!(!j||m)){k(!0);try{const h=await D.escalateTask(e.id,{source:o,priority:f,...e.projectId?{}:{projectId:i}});r(h.created?`Dieskalasi jadi ${h.spec.id}`:`Sudah tertaut ke ${h.spec.id}`,"ok","link"),l(h.task),n()}catch(h){r(Ce("mengeskalasi kartu",h),"err","x-circle")}finally{k(!1)}}}return a.jsxs(we,{open:!0,onClose:m?void 0:n,icon:"git-branch",eyebrow:"Papan tim",title:"Kirim ke Backlog",footer:a.jsxs("div",{className:"hn-dia-foot-split",children:[a.jsx("span",{className:"hn-grow"}),a.jsx(U,{variant:"secondary",onClick:n,disabled:m,children:"Batal"}),a.jsx(U,{onClick:C,loading:m,disabled:!j,leftIcon:"git-branch",children:"Kirim ke Backlog"})]}),children:[a.jsxs("div",{className:"hn-dia-lead",children:["Kartu ",a.jsx("strong",{children:e.title})," tetap di papan. Yang lahir adalah backlog item baru yang bisa dikerjakan sesi agen, dan kartu ini menampilkan stage-nya."]}),S&&a.jsxs($,{label:"Project",children:[a.jsx(B,{"aria-label":"Project",value:i,className:"hn-dia-full",onChange:h=>b(h.target.value),options:[{value:"",label:"Pilih project…"},...t.map(h=>({value:h.id,label:h.name}))]}),a.jsx("div",{className:"hn-dia-hint",children:"Nomor SPEC diambil dari repo project, jadi kartu tanpa project belum bisa dieskalasi."})]}),a.jsx($,{label:"Source",hint:"Jenis item backlog yang lahir dari kartu ini, mis. feature brief atau Finding QA.",children:a.jsx(B,{"aria-label":"Source",value:o,className:"hn-dia-full",onChange:h=>u(h.target.value),options:wt})}),a.jsx($,{label:"Prioritas",children:a.jsx(B,{"aria-label":"Prioritas",value:f,className:"hn-dia-full",onChange:h=>p(h.target.value),options:He})})]})}function Mt({m:e,busy:t,onSave:n,onToggle:l,onDelete:r}){const[o,u]=d.useState(!1),[f,p]=d.useState(e.name),[i,b]=d.useState(e.role??"");return o?a.jsxs("div",{className:"hn-mem-edit",children:[a.jsx(Y,{size:"sm",value:f,"aria-label":`Nama ${e.name}`,placeholder:"mis. Dena Meidina",onChange:m=>p(m.target.value)}),a.jsx(Y,{size:"sm",value:i,"aria-label":`Peran ${e.name}`,placeholder:"mis. desainer",onChange:m=>b(m.target.value)}),a.jsxs("div",{className:"hn-mem-note",children:[e.email," — ganti email berarti hapus lalu buat baru."]}),a.jsxs("div",{className:"hn-mem-actions",children:[a.jsx(U,{size:"sm",disabled:t,onClick:()=>{n(e.id,{name:f.trim(),role:i.trim()||null}),u(!1)},children:"Simpan"}),a.jsx(U,{size:"sm",variant:"ghost",onClick:()=>u(!1),children:"Batal"})]})]}):a.jsxs("div",{className:`hn-dense-row hn-mem-row${e.active?"":" hn-mem-row--off"}`,children:[a.jsxs("span",{className:"hn-mem-main",children:[a.jsxs("span",{className:"hn-mem-name-row",children:[a.jsx("span",{className:"hn-mem-name",children:e.name}),e.role&&a.jsx(Ze,{tone:"neutral",size:"sm",children:e.role}),!e.active&&a.jsx(Ze,{tone:"warn",size:"sm",children:"nonaktif"})]}),a.jsx("span",{className:"hn-mem-email",children:e.email})]}),a.jsx(ke,{icon:"pencil",label:`Ubah ${e.name}`,size:"sm",onClick:()=>u(!0)}),a.jsx(ke,{icon:e.active?"user-minus":"user-check",size:"sm",label:`${e.active?"Nonaktifkan":"Aktifkan"} ${e.name}`,onClick:()=>l(e)}),a.jsx(ke,{icon:"trash-2",label:`Hapus ${e.name}`,size:"sm",onClick:()=>r(e)})]})}function Et({open:e,onClose:t,onChanged:n,onToast:l}){const[r,o]=d.useState([]),[u,f]=d.useState("loading"),[p,i]=d.useState(!1),[b,m]=d.useState(!1),[k,S]=d.useState(""),[j,C]=d.useState(""),[h,N]=d.useState(""),{confirm:M,dialog:A}=ca(),g=d.useRef(n);g.current=n;const T=d.useRef(!1),c=d.useCallback(()=>{T.current||f("loading"),D.listMembers().then(v=>{T.current=!0,o(v.items),f("ready"),i(!1),g.current(v.items)}).catch(()=>{T.current?i(!0):f("error")})},[]);if(d.useEffect(()=>{e&&c()},[e,c]),!e)return null;async function y(){if(!k.trim()||!j.trim()){l("Nama & email wajib diisi","err","x-circle");return}m(!0);try{await D.createMember({name:k.trim(),email:j.trim(),role:h.trim()||null}),S(""),C(""),N(""),l("Anggota ditambahkan","ok","user-plus"),c()}catch{l("Gagal menambah anggota — email mungkin sudah terdaftar","err","x-circle")}finally{m(!1)}}async function L(v,le){m(!0);try{await D.patchMember(v,le),c()}catch{l("Gagal menyimpan anggota","err","x-circle")}finally{m(!1)}}async function I(v){m(!0);try{await D.patchMember(v.id,{active:!v.active}),c()}catch{l("Gagal mengubah status anggota","err","x-circle")}finally{m(!1)}}async function K(v){await M({title:`Hapus ${v.name} dari direktori?`,message:"Tugasnya tidak ikut terhapus — kartu yang ditugaskan padanya jadi 'belum ditugaskan'.",confirmLabel:"Hapus anggota",tone:"danger",icon:"trash-2",run:()=>D.deleteMember(v.id)})&&(l("Anggota dihapus","ok","trash-2"),c())}return a.jsxs(a.Fragment,{children:[a.jsxs(we,{open:e,onClose:t,icon:"users",eyebrow:"Papan tim",title:"Anggota",width:620,children:[a.jsxs("div",{className:"hn-mem-add",children:[a.jsx(Y,{size:"sm",value:k,"aria-label":"Nama anggota baru",placeholder:"Nama",onChange:v=>S(v.target.value),className:"hn-mem-in-name"}),a.jsx(Y,{size:"sm",value:j,"aria-label":"Email anggota baru",placeholder:"email@nafanesia.id",onChange:v=>C(v.target.value),className:"hn-mem-in-email"}),a.jsx(Y,{size:"sm",value:h,"aria-label":"Peran anggota baru",placeholder:"Peran (opsional)",onChange:v=>N(v.target.value),className:"hn-mem-in-role"}),a.jsx(U,{size:"sm",leftIcon:"user-plus",onClick:y,loading:b,children:"Tambah anggota"})]}),p&&a.jsx(Ua,{tone:"err",title:"Gagal memuat ulang anggota",className:"hn-mem-alert",action:a.jsx(U,{size:"sm",variant:"ghost",onClick:c,children:"Coba lagi"}),children:"Yang tampil di bawah adalah data lama. Coba lagi untuk memuat yang terbaru."}),u==="loading"?a.jsx(W,{kind:"loading",compact:!0}):u==="error"?a.jsx(W,{kind:"error",compact:!0,hint:"Gagal memuat anggota.",action:c,actionLabel:"Coba lagi"}):r.length===0?a.jsx(W,{kind:"empty",compact:!0,icon:"users",title:"Belum ada anggota",hint:"Tambahkan orang di atas agar kartu papan bisa ditugaskan."}):r.map(v=>a.jsx(Mt,{m:v,busy:b,onSave:L,onToggle:I,onDelete:K},v.id))]}),A]})}const $t=5e3,la=200,Lt=400,_="me",H="all",ia=[{value:"board",label:"Papan",icon:"kanban"},{value:"timeline",label:"Linimasa",icon:"gantt-chart"},{value:"projects",label:"Lintas project",icon:"layers"}],Ot={day:"Hari",week:"Minggu",month:"Bulan"},Pt=()=>Object.fromEntries(Z.map(e=>[e.key,0]));function Bt({status:e,params:t,onData:n,refetch:l}){return Wa({topic:"tasks",params:{...t,status:e},apply:r=>n(e,r.data.items,r.data.total),refetch:l,pollMs:$t}),null}function Kt({projects:e,projectFilter:t,onProjectFilter:n,onToast:l,onOpenSpec:r}){var Ke,ze,Ge;const[o,u]=d.useState(Qa),[f,p]=d.useState(Pt),[i,b]=d.useState([]),[m,k]=d.useState(""),[S,j]=d.useState("loading"),[C,h]=d.useState(!1),[N,M]=d.useState(null),[A,g]=d.useState(!1),[T,c]=d.useState(!1),[y,L]=d.useState(null),[I,K]=d.useState(null),[v,le]=Fa(),[he,ba]=X("team","view","board",Ye(...ia.map(s=>s.value))),[V,pe]=X("team","q","",xe),[z,ie]=X("team","col","all",xe),[P,ae]=X("team","member",_,xe),[ge,fa]=X("team","zoom","week",Ye(...Qe)),[ja,De]=X("team","expanded",[],Va),ka=d.useCallback(s=>{De(x=>x.includes(s)?x.filter(w=>w!==s):[...x,s])},[De]),Me=he==="timeline",F=he==="projects",Ee=d.useRef(Date.now()).current;d.useEffect(()=>{var w,E;let s=!0;const x=(E=(w=D).authStatus)==null?void 0:E.call(w);return x==null||x.then(O=>{var R;s&&K(((R=O.user)==null?void 0:R.email)??null)}).catch(()=>{s&&K(null)}),()=>{s=!1}},[]);const G=d.useMemo(()=>z==="all"?Z:Z.filter(s=>s.key===z),[z]),be=G.map(s=>s.key).join(","),fe=F||t==="all"?void 0:t,re=d.useMemo(()=>{if(!I)return null;const s=Ka(I);return i.some(x=>x.id===s)?s:null},[I,i]),oe=P===_?re??void 0:P===H?void 0:P,$e=P!==_&&P!==H,Q=d.useMemo(()=>({projectId:fe,memberId:oe,q:V.trim()||void 0}),[fe,oe,V]),ce=d.useRef(!1),te=d.useCallback((s=!1)=>{!s&&!ce.current&&j("loading");const x=be?be.split(","):[];Promise.all(x.map(w=>D.listTasks({...Q,status:w,page:1,limit:la}))).then(w=>{u(E=>{const O={...E};return x.forEach((R,ne)=>{O[R]=w[ne].items}),O}),p(E=>{const O={...E};return x.forEach((R,ne)=>{O[R]=w[ne].total}),O}),ce.current=!0,h(!1),j("ready")}).catch(()=>{if(!ce.current){j("error");return}h(!0)})},[Q,be]);d.useEffect(()=>{te()},[te]);const Le=d.useCallback(()=>{D.listMembers().then(s=>{b(s.items),k("")}).catch(s=>k(za(s,"tidak diketahui")))},[]);d.useEffect(()=>{Le()},[Le]);const[Oe,xa]=d.useState(()=>V.trim());d.useEffect(()=>{const s=setTimeout(()=>xa(V.trim()),Lt);return()=>clearTimeout(s)},[V]);const ya=d.useCallback((s,x,w)=>{u(E=>({...E,[s]:x})),p(E=>({...E,[s]:w})),ce.current=!0,h(!1),j("ready")},[]),va=d.useMemo(()=>({projectId:Q.projectId,memberId:Q.memberId,q:Oe||void 0,page:1,limit:la}),[Q.projectId,Q.memberId,Oe]),de=d.useCallback(()=>te(!0),[te]);async function Sa(s,x){var O;const w=Xa(o,s.id,s.status,x);if(!w)return;const E=o;u(w.board);try{await D.patchTask(s.id,w.patch);const R=((O=Z.find(ne=>ne.key===x))==null?void 0:O.label)??x;le(`Tugas dipindah ke ${R}`,"ok",void 0,{action:{label:"Urungkan",onAction:()=>{Pe(s.id,{status:s.status})}}})}catch{u(E),l("Gagal memindahkan tugas","err","x-circle")}}async function Ca(s,x){var E;const w=o;u(ye(o,{...s,memberId:x}));try{await D.patchTask(s.id,{memberId:x});const O=x?((E=i.find(R=>R.id===x))==null?void 0:E.name)??"anggota":null;le(O?`Ditugaskan ke ${O}`:"Penugasan dikosongkan","ok",void 0,{action:{label:"Urungkan",onAction:()=>{Pe(s.id,{memberId:s.memberId})}}})}catch{u(w),l("Gagal menugaskan","err","x-circle")}}async function Pe(s,x){try{await D.patchTask(s,x),de()}catch{l("Gagal mengurungkan perubahan","err","x-circle")}}async function Na(s){const x=o;u(ye(o,{...s,specId:null,spec:null}));try{await D.unlinkTaskSpec(s.id),l("Tautan backlog dilepas","ok","unlink")}catch{u(x),l("Gagal melepas tautan","err","x-circle")}}const Be=G.every(s=>o[s.key].length===0),je=V.trim()!=="",Ae=(!F&&t!=="all"?1:0)+(z!=="all"?1:0)+($e?1:0),Re=Ae>0||je||oe!==void 0,Ia=((Ke=e.find(s=>s.id===t))==null?void 0:Ke.name)??t,Ta=((ze=i.find(s=>s.id===P))==null?void 0:ze.name)??P,wa=((Ge=Z.find(s=>s.key===z))==null?void 0:Ge.label)??z,Da=()=>{F||n("all"),ie("all"),ae(_),pe("")},Ma=()=>{F||n("all"),ie("all"),ae(H),pe("")},_e=d.useMemo(()=>G.flatMap(s=>o[s.key]),[o,G]),Ue=G.reduce((s,x)=>s+Math.max(0,(f[x.key]??0)-o[x.key].length),0),Ea=G.reduce((s,x)=>s+(f[x.key]??0),0),Fe=[...!F&&t!=="all"?[{key:"project",label:`Project: ${Ia}`,onRemove:()=>n("all")}]:[],...z!=="all"?[{key:"col",label:`Kolom: ${wa}`,onRemove:()=>ie("all")}]:[],...$e?[{key:"member",label:`Anggota: ${Ta}`,onRemove:()=>ae(_)}]:[]],$a=[...re?[{value:_,label:"Saya"}]:[],{value:H,label:"Semua anggota"},...i.map(s=>({value:s.id,label:s.name}))],La=P===_&&!re?H:P,Oa=a.jsxs(Ga,{gap:3,children:[a.jsx($,{label:"Project",children:a.jsx(B,{size:"sm","aria-label":"Filter project",value:t,disabled:F,onChange:s=>n(s.target.value),options:[{value:"all",label:"Semua project"},...e.map(s=>({value:s.id,label:s.name}))]})}),F&&a.jsx("p",{"data-testid":"project-filter-note",className:"hn-tm-hint",children:"Mode ini melintasi semua project"}),a.jsx($,{label:"Anggota",children:a.jsx(B,{size:"sm","aria-label":"Filter anggota",value:La,disabled:!!m,onChange:s=>ae(s.target.value),options:$a})}),m&&a.jsxs("p",{role:"alert",className:"hn-tm-hint hn-tm-alert",children:["Anggota gagal dimuat: ",m]}),a.jsx($,{label:"Kolom",children:a.jsx(B,{size:"sm","aria-label":"Filter kolom",value:z,onChange:s=>ie(s.target.value),options:[{value:"all",label:"Semua kolom"},...Z.map(s=>({value:s.key,label:s.label}))]})}),(Me||F)&&a.jsx($,{label:"Zoom",children:a.jsx(B,{size:"sm","aria-label":"Zoom linimasa",value:ge,onChange:s=>fa(s.target.value),options:Qe.map(s=>({value:s,label:Ot[s]}))})})]});return a.jsxs("div",{className:"hn-tm-screen",children:[a.jsxs("section",{className:"hn-tm-toolbar",role:"region","aria-label":"Kontrol papan tim",children:[a.jsxs("div",{className:"hn-tm-switches",children:[a.jsx(Se,{variant:"pill",value:he,onChange:ba,tabs:ia,"aria-label":"Mode tampilan"}),re&&a.jsx(Se,{variant:"pill","aria-label":"Lensa tugas",value:P===H?H:P===_?_:"",onChange:s=>ae(s),tabs:[{value:_,label:"Saya"},{value:H,label:"Semua"}]}),a.jsxs("span",{className:"hn-tm-count",role:"status",title:C?"Server tak menjawab saat menyegarkan — angka ini dari muatan terakhir yang berhasil":void 0,children:[Ea," tugas",C?" · data lama":""]}),a.jsx(qa,{})]}),a.jsx(Ha,{label:"Penyaring tim",search:{value:V,onChange:pe,label:"Cari tugas",placeholder:"mis. halaman harga atau deploy"},chips:Fe,filters:Oa,filtersLabel:"Filter",onReset:Fe.length>0||je?Da:void 0,resetLabel:"Reset filter",actions:a.jsxs(a.Fragment,{children:[a.jsx(U,{size:"sm",leftIcon:"plus",onClick:()=>{M(null),g(!0)},children:"Tugas baru"}),a.jsx(Za,{onDone:de,onToast:l}),a.jsx(oa,{label:"Lainnya",items:[{key:"members",label:"Anggota tim",icon:"users",onSelect:()=>c(!0)}]})]})})]}),G.map(s=>a.jsx(Bt,{status:s.key,params:va,onData:ya,refetch:de},s.key)),S==="loading"?a.jsx(W,{kind:"loading"}):S==="error"?a.jsx(W,{kind:"error",hint:"Gagal memuat papan tim.",action:()=>te(),actionLabel:"Coba lagi"}):Be&&!Re?a.jsx(W,{kind:"empty",icon:"users",title:"Papan tim masih kosong",hint:"Catat pekerjaan manusia di sekitar sesi agen — desain, meeting klien, deploy, nego.",action:()=>{M(null),g(!0)},actionLabel:"Tugas baru",actionIcon:"plus"}):a.jsxs(a.Fragment,{children:[Be&&Re&&a.jsx(W,{kind:"empty",compact:!0,icon:"filter",title:oe!==void 0&&Ae===0&&!je?"Tak ada tugas untuk kamu":"Tak ada tugas yang cocok dengan filter",hint:"Penyaring yang aktif menyembunyikan semua tugas di papan ini.",action:Ma,actionLabel:"Tampilkan semua",actionIcon:"x"}),F?a.jsx(Nt,{tasks:_e,projects:e,members:i,zoom:ge,today:Ee,hidden:Ue,expanded:ja,onToggle:ka,onOpen:s=>{M(s),g(!0)}}):Me?a.jsx(vt,{tasks:_e,members:i,zoom:ge,today:Ee,hidden:Ue,onOpen:s=>{M(s),g(!0)}}):a.jsx(kt,{board:o,totals:f,columns:G,members:i,projects:e,onOpenSpec:r,onMove:Sa,onAssign:Ca,onEscalate:L,onUnlink:Na,onOpen:s=>{M(s),g(!0)}})]}),a.jsx(Tt,{open:A,task:N,projects:e,members:i,defaultProjectId:fe??null,orderFor:s=>da(o[s]),onClose:()=>{g(!1),M(null)},onSaved:de,onToast:l}),y&&a.jsx(Dt,{task:y,projects:e,onClose:()=>L(null),onDone:s=>u(x=>ye(x,s)),onToast:l}),a.jsx(Et,{open:T,onClose:()=>c(!1),onChanged:b,onToast:l}),a.jsx(Ya,{toast:v})]})}export{ia as TEAM_VIEWS,Kt as TeamScreen};
1
+ import{T as ra,a as Pa,b as Ba,j as a,c as Se,O as oa,P as me,I as q,d as ca,M as we,e as $,f as Y,g as B,H as Aa,B as U,h as D,i as Ce,k as He,E as Ra,s as _a,C as Ua,m as W,n as Ze,o as ke,p as Fa,q as X,r as Ye,t as Ka,v as za,w as Ga,x as Ha,y as Za,z as Ya,A as Va,D as xe,G as Wa}from"./index-C4Py9MJV.js";import{R as d}from"./react-DfGhg7ZW.js";import{L as qa}from"./live-CBa_7-hn.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";const Ja=Pa,Z=ra.map(e=>({key:e,label:Ja[e]})),Qa=()=>Object.fromEntries(ra.map(e=>[e,[]])),Ne=(e,t)=>e!==t,da=e=>e.length===0?0:e.reduce((t,n)=>n.order>t?n.order:t,-1/0)+1;function Xa(e,t,n,l){if(!Ne(n,l))return null;const r=e[n].find(f=>f.id===t);if(!r)return null;const o={status:l,order:da(e[l])},u={...e};return u[n]=e[n].filter(f=>f.id!==t),u[l]=[...e[l],{...r,...o}],{board:u,patch:o}}function ye(e,t){const n={...e};return n[t.status]=e[t.status].map(l=>l.id===t.id?t:l),n}const Ve=e=>e?e.slice(0,10):"",We=e=>/^\d{4}-\d{2}-\d{2}$/.test(e)?`${e}T12:00:00.000Z`:null,J=864e5,se=e=>Math.floor(e/J)*J,qe=e=>{if(!e)return null;const t=new Date(e).getTime();return Number.isFinite(t)?t:null};function ee(e){const t=qe(e.startDate),n=qe(e.dueDate);if(t===null&&n===null)return null;const l=t??n,r=n??t;return{start:se(Math.min(l,r)),end:se(Math.max(l,r))+J,invalid:r<l}}const et=new Intl.DateTimeFormat("id-ID",{day:"numeric",month:"short",timeZone:"UTC"}),Je=e=>e?et.format(new Date(e)):null;function ue(e){const t=Je(e.startDate),n=Je(e.dueDate);return t&&n?`${t} → ${n}`:n?`→ ${n}`:t}const Qe=["day","week","month"],ua={day:{cell:34,minTicks:14},week:{cell:56,minTicks:8},month:{cell:84,minTicks:6}},at=e=>ua[e].cell,tt=120,nt=(e,t)=>{const n=se(e);if(t==="day")return n;if(t==="week")return n-(new Date(n).getUTCDay()+6)%7*J;const l=new Date(n);return Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),1)},st=(e,t)=>{if(t==="day")return e+J;if(t==="week")return e+7*J;const n=new Date(e);return Date.UTC(n.getUTCFullYear(),n.getUTCMonth()+1,1)},lt=new Intl.DateTimeFormat("id-ID",{day:"numeric",timeZone:"UTC"}),Xe=new Intl.DateTimeFormat("id-ID",{day:"numeric",month:"short",timeZone:"UTC"}),it=new Intl.DateTimeFormat("id-ID",{month:"short",timeZone:"UTC"}),rt=new Intl.DateTimeFormat("id-ID",{month:"short",year:"2-digit",timeZone:"UTC"}),ot=(e,t)=>{const n=new Date(e);return t==="day"?n.getUTCDate()===1:t==="week"?n.getUTCDate()<=7:n.getUTCMonth()===0},ct=(e,t,n)=>{const l=new Date(e);return t==="day"?(n?Xe:lt).format(l):t==="week"?Xe.format(l):(n?rt:it).format(l)};function ma(e,t,n){const l=se(n);let r=l,o=l+J;for(const b of e)b.start<r&&(r=b.start),b.end>o&&(o=b.end);const u=nt(r,t),{minTicks:f}=ua[t],p=[];let i=u;for(;p.length<tt&&(i<o||p.length<f);){const b=ot(i,t);p.push({start:i,label:ct(i,t,b),major:b}),i=st(i,t)}return{from:u,to:i,zoom:t,ticks:p}}function ha(e,t){const n=t.to-t.from;if(n<=0||e.end<=t.from||e.start>=t.to)return null;const l=Math.max(e.start,t.from),r=Math.min(e.end,t.to);return{left:(l-t.from)/n*100,width:(r-l)/n*100,clippedStart:e.start<t.from,clippedEnd:e.end>t.to,invalid:e.invalid}}function Ie(e,t){const n=ee(e);return n?ha(n,t):null}function dt(e){let t=1/0,n=-1/0,l=!1;for(const r of e){const o=ee(r);o&&(o.start<t&&(t=o.start),o.end>n&&(n=o.end),o.invalid&&(l=!0))}return t===1/0?null:{start:t,end:n,invalid:l}}function ut(e,t){const n=se(t);return n<e.from||n>=e.to?null:(n-e.from)/(e.to-e.from)*100}function mt(e,t){const n=[],l=[],r=[];for(const o of e){const u=ee(o);if(!u){l.push(o);continue}const f=Ie(o,t);if(!f){r.push(o);continue}n.push({task:o,geometry:f,start:u.start})}return n.sort((o,u)=>o.start-u.start||o.task.title.localeCompare(u.task.title,"id")||o.task.id.localeCompare(u.task.id)),{rows:n.map(({task:o,geometry:u})=>({task:o,geometry:u})),unscheduled:l,outside:r}}const ea=(e,t)=>e.title.localeCompare(t.title,"id")||e.id.localeCompare(t.id);function ht(e,t,n){const l=Symbol("no-project"),r=new Map;for(const p of e){const i=p.projectId??l,b=r.get(i);b?b.tasks.push(p):r.set(i,{projectId:p.projectId,tasks:[p]})}const o=[...r.values()].map(({projectId:p,tasks:i})=>{const b=dt(i),m=[],k=[];for(const S of i){const j=ee(S);j?m.push({task:S,start:j.start}):k.push(S)}return m.sort((S,j)=>S.start-j.start||ea(S.task,j.task)),k.sort(ea),{projectId:p,span:b,geometry:b?ha(b,t):null,tasks:[...m.map(S=>S.task),...k]}}),u=p=>p.geometry?0:p.span?1:2,f=p=>p.projectId===null?[1,""]:[0,p.projectId];return o.sort((p,i)=>{const[b,m]=f(p),[k,S]=f(i);return u(p)-u(i)||(p.span&&i.span?p.span.start-i.span.start:0)||n(p.projectId).localeCompare(n(i.projectId),"id")||b-k||m.localeCompare(S)}),o}const pt={tinggi:"high",sedang:"mid",rendah:"low"};function gt({priority:e}){const t=pt[e]??"mid",n=me[e]??e;return a.jsx("span",{className:`hn-tm-prio hn-tm-prio-${t}`,title:`Prioritas ${n}`,children:a.jsxs("span",{className:"hn-sr-only",children:["Prioritas ",n]})})}function bt({name:e}){if(!e)return a.jsx("span",{className:"hn-tm-avatar hn-tm-avatar-empty","aria-hidden":"true",children:a.jsx(q,{name:"user",size:12})});const t=e.split(/\s+/).filter(Boolean).slice(0,2).map(n=>n[0].toUpperCase()).join("");return a.jsx("span",{className:"hn-tm-avatar","aria-hidden":"true",children:t||"?"})}function ft(e,t,n){const l=[...Z.filter(r=>r.key!==e.status).map(r=>({key:`move-${r.key}`,label:`Pindah ke ${r.label}`,onSelect:()=>n.onMove(e,r.key)})),...t.map(r=>({key:`assign-${r.id}`,label:`Tugaskan ke ${r.name}`,disabled:e.memberId===r.id,onSelect:()=>n.onAssign(e,r.id)})),{key:"assign-none",label:"Kosongkan penugasan",disabled:!e.memberId,onSelect:()=>n.onAssign(e,null)}];if(e.specId){if(e.spec&&n.onOpenSpec){const r=e.specId;l.push({key:"open-spec",label:`Buka ${e.spec.id} di Backlog`,onSelect:()=>{var o;return(o=n.onOpenSpec)==null?void 0:o.call(n,r)}})}l.push({key:"unlink",label:e.spec?"Lepas tautan":"Lepas tautan (spec tak ditemukan)",onSelect:()=>n.onUnlink(e)})}else l.push({key:"escalate",label:"Kirim ke Backlog",onSelect:()=>n.onEscalate(e)});return l}function jt({task:e,members:t,projectName:n,dragging:l,onDragStart:r,onDragEnd:o,onOpen:u,onMove:f,onAssign:p,onEscalate:i,onUnlink:b,onOpenSpec:m}){var C;const k=((C=t.find(h=>h.id===e.memberId))==null?void 0:C.name)??null,S=ft(e,t,{onMove:f,onAssign:p,onEscalate:i,onUnlink:b,onOpenSpec:m}),j=e.projectId===null?"tanpa project":n??"project tak dikenal";return a.jsxs("div",{draggable:!0,"data-testid":`team-card-${e.id}`,className:"hn-tm-card","data-dragging":l||void 0,title:`Project: ${j}`,onDragStart:h=>{h.dataTransfer.effectAllowed="move",h.dataTransfer.setData("text/plain",e.id),r()},onDragEnd:o,children:[a.jsxs("div",{className:"hn-tm-card-head",children:[a.jsx(gt,{priority:e.priority}),a.jsx("button",{type:"button",className:"hn-tm-title",onClick:()=>u(e),children:e.title})]}),a.jsx("span",{className:"hn-tm-project","data-empty":e.projectId===null||void 0,children:j}),a.jsxs("div",{className:"hn-tm-card-foot",children:[a.jsxs("span",{className:"hn-tm-assignee-wrap",children:[a.jsx(bt,{name:k}),a.jsx("span",{className:"hn-tm-assignee",children:k??"belum ditugaskan"})]}),a.jsx(oa,{label:`Ubah tugas: ${e.title}`,icon:"ellipsis",items:S})]})]})}function kt({board:e,totals:t,columns:n,members:l,projects:r=[],onMove:o,onAssign:u,onOpen:f,onEscalate:p,onUnlink:i,onOpenSpec:b}){var T;const[m,k]=d.useState(null),[S,j]=d.useState(null),C=Ba(),[h,N]=d.useState(((T=n[0])==null?void 0:T.key)??"backlog"),M=d.useMemo(()=>{const c=new Map(r.map(y=>[y.id,y.name]));return y=>y===null?null:c.get(y)??null},[r]),A=c=>{m&&Ne(m.from,c)&&o(m.task,c),k(null),j(null)},g=(c,y)=>a.jsx(jt,{task:c,members:l,projectName:M(c.projectId),dragging:(m==null?void 0:m.task.id)===c.id,onDragStart:()=>k({task:c,from:y}),onDragEnd:()=>{k(null),j(null)},onOpen:f,onMove:o,onAssign:u,onEscalate:p,onUnlink:i,onOpenSpec:b},c.id);if(C==="mobile"){const c=n.find(I=>I.key===h)??n[0];if(!c)return null;const y=e[c.key],L=Math.max(0,(t[c.key]??0)-y.length);return a.jsxs("div",{"data-testid":"team-board","data-layout":"mobile",className:"hn-tm-mobile",children:[a.jsx(Se,{variant:"pill","aria-label":"Kolom papan tim",value:c.key,onChange:I=>N(I),tabs:n.map(I=>({value:I.key,label:`${I.label} · ${e[I.key].length}`}))}),a.jsxs("div",{"data-testid":`team-col-${c.key}`,className:"hn-tm-col-stack",children:[y.map(I=>g(I,c.key)),y.length===0&&a.jsxs("div",{className:"hn-tm-empty-col",children:["Tak ada tugas di ",c.label,"."]}),L>0&&a.jsxs("div",{className:"hn-tm-hidden-note",children:["menampilkan ",y.length," dari ",t[c.key]," — persempit penyaring"]})]})]})}return a.jsx("div",{"data-testid":"team-board",className:"hn-board-local-overflow hn-tm-board",children:n.map(c=>{const y=e[c.key],L=!!m&&Ne(m.from,c.key),I=L&&S===c.key,K=Math.max(0,(t[c.key]??0)-y.length);return a.jsxs("div",{"data-testid":`team-col-${c.key}`,className:"hn-tm-col","data-active":L||void 0,"data-hot":I||void 0,"data-dimmed":m&&!L||void 0,onDragOver:v=>{L&&(v.preventDefault(),v.dataTransfer.dropEffect="move",j(c.key))},onDragLeave:()=>j(v=>v===c.key?null:v),onDrop:v=>{v.preventDefault(),A(c.key)},children:[a.jsxs("div",{className:"hn-tm-col-head",children:[a.jsx("span",{className:"hn-eyebrow",children:c.label}),a.jsx("span",{className:"hn-tm-col-count",children:y.length})]}),a.jsx("div",{className:"hn-tm-col-body",children:y.map(v=>g(v,c.key))}),K>0&&a.jsxs("div",{className:"hn-tm-hidden-note",children:["menampilkan ",y.length," dari ",t[c.key]," — persempit penyaring"]})]},c.key)})})}const ve=232,xt={brass:"var(--brass-500)",err:"var(--status-err)",muted:"var(--border-strong)",envelope:"var(--border-hair)"},Te=e=>e;function yt({spec:e}){const t=e.geometry,n=xt[e.tone],l=!!e.onClick,r={"data-testid":`timeline-bar-${e.key}`,"data-tone":e.tone,"data-invalid":t.invalid?"true":"false","data-clipped-start":t.clippedStart?"true":"false","data-clipped-end":t.clippedEnd?"true":"false",title:e.title,"aria-label":e.title,onClick:e.onClick,className:"hn-tl-bar",style:Te({"--tl-left":`${t.left}%`,"--tl-width":`${t.width}%`})},o=a.jsxs(a.Fragment,{children:[t.invalid&&a.jsx(q,{name:"triangle-alert",size:11,color:n}),t.clippedStart&&a.jsx(q,{name:"chevron-left",size:11,color:n}),a.jsx("span",{className:"hn-grow"}),t.clippedEnd&&a.jsx(q,{name:"chevron-right",size:11,color:n})]});return l?a.jsx("button",{type:"button",...r,children:o}):a.jsx("div",{role:"img",...r,children:o})}function pa({envelope:e=!1}){const t=n=>a.jsx("span",{"aria-hidden":"true",className:"hn-tl-swatch","data-tone":n});return a.jsxs("ul",{"aria-label":"Legenda linimasa",className:"hn-tl-legend",children:[a.jsxs("li",{className:"hn-tl-legend-item",children:[t("brass"),"Rencana"]}),a.jsxs("li",{className:"hn-tl-legend-item",children:[t("muted"),"Selesai"]}),a.jsxs("li",{className:"hn-tl-legend-item",children:[t("err"),a.jsx(q,{name:"triangle-alert",size:11,color:"var(--status-err)"}),"Tenggat mendahului mulai"]}),e&&a.jsxs("li",{className:"hn-tl-legend-item",children:[t("envelope"),"Rentang project (buka lewat namanya)"]})]})}function ga({window:e,rows:t,today:n,emptyHint:l,testId:r,labelHead:o}){const u=at(e.zoom),f=e.ticks.length*u,p=ut(e,n);return a.jsx("div",{"data-testid":r??"team-timeline",className:"hn-timeline-scroll hn-tl-scroll",children:a.jsxs("div",{"data-testid":"timeline-canvas",className:"hn-tl",style:Te({"--tl-label-w":`${ve}px`,"--tl-cell":`${u}px`,"--tl-ticks":String(e.ticks.length),"--tl-track-w":`${f}px`,"--tl-canvas-w":`${ve+f}px`}),children:[a.jsxs("div",{className:"hn-tl-head",children:[a.jsx("div",{className:"hn-tl-label",children:a.jsx("span",{className:"hn-eyebrow",children:o??"Tugas"})}),a.jsx("div",{className:"hn-tl-ticks",children:e.ticks.map(i=>a.jsx("div",{"data-testid":"timeline-tick","data-major":i.major?"true":"false",className:"hn-tl-tick",children:i.label},i.start))})]}),t.length===0?a.jsx("div",{"data-testid":"timeline-empty",className:"hn-tl-empty",children:l??"Tak ada yang bisa dihamparkan di jendela ini."}):t.map(i=>a.jsxs("div",{"data-testid":`timeline-row-${i.key}`,className:"hn-tl-row",children:[a.jsxs("div",{className:"hn-tl-label",children:[a.jsx("div",{className:"hn-tl-label-text",children:i.label}),i.meta&&a.jsx("div",{className:"hn-tl-label-meta",children:i.meta})]}),a.jsx("div",{className:"hn-tl-track",children:i.bars.map(b=>a.jsx(yt,{spec:b},b.key))})]},i.key)),p!==null&&a.jsx("div",{"data-testid":"timeline-today","aria-hidden":"true",className:"hn-tl-today",style:Te({"--tl-today-x":`${ve+p/100*f}px`})})]})})}function aa({testId:e,icon:t,title:n,hint:l,tasks:r,onOpen:o}){return r.length===0?null:a.jsxs("div",{"data-testid":e,className:"hn-tl-aside",children:[a.jsxs("div",{className:"hn-tl-aside-head",children:[a.jsx(q,{name:t,size:13,color:"var(--text-subtle)"}),a.jsxs("span",{className:"hn-eyebrow",children:[n," · ",r.length]}),l&&a.jsx("span",{className:"hn-tl-aside-hint",children:l})]}),a.jsx("div",{className:"hn-tl-aside-list",children:r.map(u=>a.jsx("button",{type:"button",onClick:()=>o(u),className:"hn-tl-chip",children:u.title},u.id))})]})}function vt({tasks:e,members:t,zoom:n,today:l,hidden:r,onOpen:o}){const u=d.useMemo(()=>{const m=e.map(ee).filter(k=>k!==null);return ma(m,n,l)},[e,n,l]),{rows:f,unscheduled:p,outside:i}=d.useMemo(()=>mt(e,u),[e,u]),b=d.useMemo(()=>f.map(({task:m,geometry:k})=>{var h;const S=((h=t.find(N=>N.id===m.memberId))==null?void 0:h.name)??"belum ditugaskan",j=ue(m),C=[k.invalid?"tenggat mendahului mulai":null,k.clippedStart||k.clippedEnd?"melewati tepi jendela":null].filter(Boolean);return{key:m.id,label:m.title,meta:j?`${S} · ${j}`:S,bars:[{key:m.id,geometry:k,tone:k.invalid?"err":m.status==="done"?"muted":"brass",title:[m.title,j,...C].filter(Boolean).join(" · "),onClick:()=>o(m)}]}}),[f,t,o]);return a.jsxs(a.Fragment,{children:[a.jsx(pa,{}),a.jsx(ga,{window:u,rows:b,today:l,emptyHint:"Belum ada tugas bertanggal — isi mulai atau tenggat di kartunya."}),r>0&&a.jsxs("div",{"data-testid":"timeline-truncated",className:"hn-tl-note",children:[r," tugas tak termuat karena plafon 200 per kolom — persempit penyaring"]}),a.jsx(aa,{testId:"timeline-unscheduled",icon:"calendar-off",title:"Belum dijadwalkan",tasks:p,onOpen:o}),a.jsx(aa,{testId:"timeline-outside",icon:"chevrons-left-right",title:"Di luar jendela",hint:"pilih zoom yang lebih lebar",tasks:i,onOpen:o})]})}const St="__none__",ta=(e,t)=>t.invalid?"err":e.status==="done"?"muted":"brass",na=(e,t,n)=>[e.title,n,t.invalid?"tenggat mendahului mulai":null,t.clippedStart||t.clippedEnd?"melewati tepi jendela":null].filter(Boolean).join(" · ");function Ct({testId:e,open:t,name:n,count:l,onClick:r}){return a.jsxs("button",{type:"button",onClick:r,"data-testid":e,"aria-expanded":t,className:"hn-tl-expand",children:[a.jsx(q,{name:t?"chevron-down":"chevron-right",size:12,color:"var(--text-subtle)"}),a.jsx("span",{className:"hn-tl-expand-name",children:n}),a.jsx("span",{className:"hn-tl-expand-count",children:l})]})}function Nt({tasks:e,projects:t,members:n,zoom:l,today:r,hidden:o,expanded:u,onToggle:f,onOpen:p}){const i=d.useMemo(()=>{const j=e.map(ee).filter(C=>C!==null);return ma(j,l,r)},[e,l,r]),b=d.useCallback(j=>{var C;return j===null?"Tanpa project":((C=t.find(h=>h.id===j))==null?void 0:C.name)??j},[t]),m=d.useMemo(()=>ht(e,i,b),[e,i,b]),k=d.useMemo(()=>new Set(u),[u]),S=d.useMemo(()=>{var C;const j=[];for(const h of m){const N=h.projectId??St,M=k.has(N),A=b(h.projectId),g=h.geometry?ue({startDate:new Date(h.span.start).toISOString(),dueDate:new Date(h.span.end-1).toISOString()}):h.span?"di luar jendela · pilih zoom yang lebih lebar":"belum dijadwalkan",T=[];if(h.geometry){T.push({key:`span:${N}`,geometry:h.geometry,tone:h.geometry.invalid?"err":"envelope",title:`${A} · ${g??""}`.trim()});for(const c of h.tasks){const y=Ie(c,i);y&&T.push({key:`seg:${c.id}`,geometry:y,tone:ta(c,y),title:na(c,y,ue(c)),onClick:()=>p(c)})}}if(j.push({key:`p:${N}`,meta:g,bars:T,label:a.jsx(Ct,{testId:`expand-${N}`,open:M,name:A,count:h.tasks.length,onClick:()=>f(N)})}),!!M)for(const c of h.tasks){const y=Ie(c,i),L=((C=n.find(K=>K.id===c.memberId))==null?void 0:C.name)??"belum ditugaskan",I=ue(c);j.push({key:`t:${c.id}`,label:a.jsx("span",{className:"hn-tl-child",children:c.title}),meta:I?`${L} · ${I}`:L,bars:y?[{key:`t:${c.id}`,geometry:y,tone:ta(c,y),title:na(c,y,I),onClick:()=>p(c)}]:[]})}}return j},[m,k,b,i,n,f,p]);return a.jsxs(a.Fragment,{children:[a.jsx(pa,{envelope:!0}),a.jsx(ga,{window:i,rows:S,today:r,testId:"team-projects",labelHead:"Project",emptyHint:"Belum ada project bertanggal — isi mulai atau tenggat di kartunya."}),o>0&&a.jsxs("div",{"data-testid":"projects-truncated",className:"hn-tl-note",children:[o," tugas tak termuat karena plafon 200 per kolom — amplop project bisa lebih pendek dari rentang sebenarnya; persempit kolom, anggota, atau pencarian"]})]})}const It=Object.keys(me).map(e=>({value:e,label:me[e]})),sa=(e,t)=>({title:(e==null?void 0:e.title)??"",detail:(e==null?void 0:e.detail)??"",projectId:e?e.projectId??"":t??"",status:(e==null?void 0:e.status)??"backlog",priority:e&&e.priority in me?e.priority:"sedang",memberId:(e==null?void 0:e.memberId)??"",startDate:Ve((e==null?void 0:e.startDate)??null),dueDate:Ve((e==null?void 0:e.dueDate)??null)});function Tt({open:e,task:t,projects:n,members:l,defaultProjectId:r,orderFor:o,onClose:u,onSaved:f,onToast:p}){const[i,b]=d.useState(()=>sa(t,r)),[m,k]=d.useState(!1),{confirm:S,dialog:j}=ca(),C=`${e?"1":"0"}:${(t==null?void 0:t.id)??""}`,h=d.useRef(C);if(h.current!==C&&(h.current=C,e&&b(sa(t,r))),!e)return null;const N=g=>b(T=>({...T,...g}));async function M(){if(!i.title.trim()){p("Judul tugas wajib diisi","err","x-circle");return}k(!0);const g=!t||t.status!==i.status,T={title:i.title.trim(),detail:i.detail.trim()||null,projectId:i.projectId||null,status:i.status,priority:i.priority,memberId:i.memberId||null,startDate:We(i.startDate),dueDate:We(i.dueDate),...g?{order:o(i.status)}:{}};try{t?await D.patchTask(t.id,T):await D.createTask(T),p(t?"Tugas diperbarui":"Tugas dibuat","ok","check"),f(),u()}catch(c){p(Ce("menyimpan tugas",c),"err","x-circle")}finally{k(!1)}}async function A(){if(t){try{if(!await S({title:`Hapus "${t.title}"?`,impact:["Kartu ini hilang dari papan di semua device yang tersinkron."],confirmLabel:"Hapus tugas",tone:"danger",icon:"trash-2",run:async()=>{k(!0);try{await D.deleteTask(t.id)}finally{k(!1)}}}))return}catch(g){p(Ce("menghapus tugas",g),"err","x-circle");return}p("Tugas dihapus","ok","trash-2"),f(),u()}}return a.jsxs(a.Fragment,{children:[a.jsxs(we,{open:e,onClose:m?void 0:u,icon:"clipboard-list",eyebrow:"Papan tim",title:t?"Ubah tugas":"Tugas baru",footer:a.jsxs("div",{style:{display:"flex",gap:8,width:"100%",alignItems:"center"},children:[t&&a.jsx(U,{variant:"ghost",leftIcon:"trash-2",onClick:A,disabled:m,children:"Hapus"}),a.jsx("span",{style:{flex:1}}),a.jsx(U,{variant:"secondary",onClick:u,disabled:m,children:"Batal"}),a.jsx(U,{onClick:M,loading:m,children:t?"Simpan":"Buat tugas"})]}),children:[a.jsx($,{label:"Judul",children:a.jsx(Y,{value:i.title,"aria-label":"Judul tugas",placeholder:"mis. Rapikan halaman harga",onChange:g=>N({title:g.target.value}),style:{width:"100%"}})}),a.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[a.jsx($,{label:"Project",children:a.jsx(B,{value:i.projectId,"aria-label":"Project tugas",onChange:g=>N({projectId:g.target.value}),options:[{value:"",label:"Tanpa project"},...n.map(g=>({value:g.id,label:g.name}))]})}),a.jsx($,{label:"Kolom",children:a.jsx(B,{value:i.status,"aria-label":"Kolom tugas",onChange:g=>N({status:g.target.value}),options:Z.map(g=>({value:g.key,label:g.label}))})}),a.jsx($,{label:"Prioritas",children:a.jsx(B,{value:i.priority,"aria-label":"Prioritas tugas",onChange:g=>N({priority:g.target.value}),options:It})})]}),a.jsx($,{label:"Ditugaskan ke",children:a.jsx(B,{value:i.memberId,"aria-label":"Anggota tugas",onChange:g=>N({memberId:g.target.value}),options:[{value:"",label:"Belum ditugaskan"},...l.map(g=>({value:g.id,label:g.role?`${g.name} · ${g.role}`:g.name}))],style:{width:"100%"}})}),a.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[a.jsx($,{label:"Mulai",children:a.jsx(Y,{type:"date",value:i.startDate,"aria-label":"Tanggal mulai",onChange:g=>N({startDate:g.target.value})})}),a.jsx($,{label:"Tenggat",children:a.jsx(Y,{type:"date",value:i.dueDate,"aria-label":"Tanggal tenggat",onChange:g=>N({dueDate:g.target.value})})})]}),a.jsx($,{label:"Detail",hint:"Opsional — konteks yang tak muat di judul.",children:a.jsx(Aa,{value:i.detail,"aria-label":"Detail tugas",rows:4,placeholder:"mis. tunggu aset dari klien, deadline ikut jadwal kampanye",onChange:g=>N({detail:g.target.value})})})]}),j]})}const wt=Ra.map(e=>({value:e,label:_a(e).label}));function Dt({task:e,projects:t,onClose:n,onDone:l,onToast:r}){const[o,u]=d.useState("brief"),[f,p]=d.useState(()=>He.some(h=>h.value===e.priority)?e.priority:"sedang"),[i,b]=d.useState(""),[m,k]=d.useState(!1),S=e.projectId===null,j=e.projectId??i;async function C(){if(!(!j||m)){k(!0);try{const h=await D.escalateTask(e.id,{source:o,priority:f,...e.projectId?{}:{projectId:i}});r(h.created?`Dieskalasi jadi ${h.spec.id}`:`Sudah tertaut ke ${h.spec.id}`,"ok","link"),l(h.task),n()}catch(h){r(Ce("mengeskalasi kartu",h),"err","x-circle")}finally{k(!1)}}}return a.jsxs(we,{open:!0,onClose:m?void 0:n,icon:"git-branch",eyebrow:"Papan tim",title:"Kirim ke Backlog",footer:a.jsxs("div",{className:"hn-dia-foot-split",children:[a.jsx("span",{className:"hn-grow"}),a.jsx(U,{variant:"secondary",onClick:n,disabled:m,children:"Batal"}),a.jsx(U,{onClick:C,loading:m,disabled:!j,leftIcon:"git-branch",children:"Kirim ke Backlog"})]}),children:[a.jsxs("div",{className:"hn-dia-lead",children:["Kartu ",a.jsx("strong",{children:e.title})," tetap di papan. Yang lahir adalah backlog item baru yang bisa dikerjakan sesi agen, dan kartu ini menampilkan stage-nya."]}),S&&a.jsxs($,{label:"Project",children:[a.jsx(B,{"aria-label":"Project",value:i,className:"hn-dia-full",onChange:h=>b(h.target.value),options:[{value:"",label:"Pilih project…"},...t.map(h=>({value:h.id,label:h.name}))]}),a.jsx("div",{className:"hn-dia-hint",children:"Nomor SPEC diambil dari repo project, jadi kartu tanpa project belum bisa dieskalasi."})]}),a.jsx($,{label:"Source",hint:"Jenis item backlog yang lahir dari kartu ini, mis. feature brief atau Finding QA.",children:a.jsx(B,{"aria-label":"Source",value:o,className:"hn-dia-full",onChange:h=>u(h.target.value),options:wt})}),a.jsx($,{label:"Prioritas",children:a.jsx(B,{"aria-label":"Prioritas",value:f,className:"hn-dia-full",onChange:h=>p(h.target.value),options:He})})]})}function Mt({m:e,busy:t,onSave:n,onToggle:l,onDelete:r}){const[o,u]=d.useState(!1),[f,p]=d.useState(e.name),[i,b]=d.useState(e.role??"");return o?a.jsxs("div",{className:"hn-mem-edit",children:[a.jsx(Y,{size:"sm",value:f,"aria-label":`Nama ${e.name}`,placeholder:"mis. Dena Meidina",onChange:m=>p(m.target.value)}),a.jsx(Y,{size:"sm",value:i,"aria-label":`Peran ${e.name}`,placeholder:"mis. desainer",onChange:m=>b(m.target.value)}),a.jsxs("div",{className:"hn-mem-note",children:[e.email," — ganti email berarti hapus lalu buat baru."]}),a.jsxs("div",{className:"hn-mem-actions",children:[a.jsx(U,{size:"sm",disabled:t,onClick:()=>{n(e.id,{name:f.trim(),role:i.trim()||null}),u(!1)},children:"Simpan"}),a.jsx(U,{size:"sm",variant:"ghost",onClick:()=>u(!1),children:"Batal"})]})]}):a.jsxs("div",{className:`hn-dense-row hn-mem-row${e.active?"":" hn-mem-row--off"}`,children:[a.jsxs("span",{className:"hn-mem-main",children:[a.jsxs("span",{className:"hn-mem-name-row",children:[a.jsx("span",{className:"hn-mem-name",children:e.name}),e.role&&a.jsx(Ze,{tone:"neutral",size:"sm",children:e.role}),!e.active&&a.jsx(Ze,{tone:"warn",size:"sm",children:"nonaktif"})]}),a.jsx("span",{className:"hn-mem-email",children:e.email})]}),a.jsx(ke,{icon:"pencil",label:`Ubah ${e.name}`,size:"sm",onClick:()=>u(!0)}),a.jsx(ke,{icon:e.active?"user-minus":"user-check",size:"sm",label:`${e.active?"Nonaktifkan":"Aktifkan"} ${e.name}`,onClick:()=>l(e)}),a.jsx(ke,{icon:"trash-2",label:`Hapus ${e.name}`,size:"sm",onClick:()=>r(e)})]})}function Et({open:e,onClose:t,onChanged:n,onToast:l}){const[r,o]=d.useState([]),[u,f]=d.useState("loading"),[p,i]=d.useState(!1),[b,m]=d.useState(!1),[k,S]=d.useState(""),[j,C]=d.useState(""),[h,N]=d.useState(""),{confirm:M,dialog:A}=ca(),g=d.useRef(n);g.current=n;const T=d.useRef(!1),c=d.useCallback(()=>{T.current||f("loading"),D.listMembers().then(v=>{T.current=!0,o(v.items),f("ready"),i(!1),g.current(v.items)}).catch(()=>{T.current?i(!0):f("error")})},[]);if(d.useEffect(()=>{e&&c()},[e,c]),!e)return null;async function y(){if(!k.trim()||!j.trim()){l("Nama & email wajib diisi","err","x-circle");return}m(!0);try{await D.createMember({name:k.trim(),email:j.trim(),role:h.trim()||null}),S(""),C(""),N(""),l("Anggota ditambahkan","ok","user-plus"),c()}catch{l("Gagal menambah anggota — email mungkin sudah terdaftar","err","x-circle")}finally{m(!1)}}async function L(v,le){m(!0);try{await D.patchMember(v,le),c()}catch{l("Gagal menyimpan anggota","err","x-circle")}finally{m(!1)}}async function I(v){m(!0);try{await D.patchMember(v.id,{active:!v.active}),c()}catch{l("Gagal mengubah status anggota","err","x-circle")}finally{m(!1)}}async function K(v){await M({title:`Hapus ${v.name} dari direktori?`,message:"Tugasnya tidak ikut terhapus — kartu yang ditugaskan padanya jadi 'belum ditugaskan'.",confirmLabel:"Hapus anggota",tone:"danger",icon:"trash-2",run:()=>D.deleteMember(v.id)})&&(l("Anggota dihapus","ok","trash-2"),c())}return a.jsxs(a.Fragment,{children:[a.jsxs(we,{open:e,onClose:t,icon:"users",eyebrow:"Papan tim",title:"Anggota",width:620,children:[a.jsxs("div",{className:"hn-mem-add",children:[a.jsx(Y,{size:"sm",value:k,"aria-label":"Nama anggota baru",placeholder:"Nama",onChange:v=>S(v.target.value),className:"hn-mem-in-name"}),a.jsx(Y,{size:"sm",value:j,"aria-label":"Email anggota baru",placeholder:"email@nafanesia.id",onChange:v=>C(v.target.value),className:"hn-mem-in-email"}),a.jsx(Y,{size:"sm",value:h,"aria-label":"Peran anggota baru",placeholder:"Peran (opsional)",onChange:v=>N(v.target.value),className:"hn-mem-in-role"}),a.jsx(U,{size:"sm",leftIcon:"user-plus",onClick:y,loading:b,children:"Tambah anggota"})]}),p&&a.jsx(Ua,{tone:"err",title:"Gagal memuat ulang anggota",className:"hn-mem-alert",action:a.jsx(U,{size:"sm",variant:"ghost",onClick:c,children:"Coba lagi"}),children:"Yang tampil di bawah adalah data lama. Coba lagi untuk memuat yang terbaru."}),u==="loading"?a.jsx(W,{kind:"loading",compact:!0}):u==="error"?a.jsx(W,{kind:"error",compact:!0,hint:"Gagal memuat anggota.",action:c,actionLabel:"Coba lagi"}):r.length===0?a.jsx(W,{kind:"empty",compact:!0,icon:"users",title:"Belum ada anggota",hint:"Tambahkan orang di atas agar kartu papan bisa ditugaskan."}):r.map(v=>a.jsx(Mt,{m:v,busy:b,onSave:L,onToggle:I,onDelete:K},v.id))]}),A]})}const $t=5e3,la=200,Lt=400,_="me",H="all",ia=[{value:"board",label:"Papan",icon:"kanban"},{value:"timeline",label:"Linimasa",icon:"gantt-chart"},{value:"projects",label:"Lintas project",icon:"layers"}],Ot={day:"Hari",week:"Minggu",month:"Bulan"},Pt=()=>Object.fromEntries(Z.map(e=>[e.key,0]));function Bt({status:e,params:t,onData:n,refetch:l}){return Wa({topic:"tasks",params:{...t,status:e},apply:r=>n(e,r.data.items,r.data.total),refetch:l,pollMs:$t}),null}function Kt({projects:e,projectFilter:t,onProjectFilter:n,onToast:l,onOpenSpec:r}){var Ke,ze,Ge;const[o,u]=d.useState(Qa),[f,p]=d.useState(Pt),[i,b]=d.useState([]),[m,k]=d.useState(""),[S,j]=d.useState("loading"),[C,h]=d.useState(!1),[N,M]=d.useState(null),[A,g]=d.useState(!1),[T,c]=d.useState(!1),[y,L]=d.useState(null),[I,K]=d.useState(null),[v,le]=Fa(),[he,ba]=X("team","view","board",Ye(...ia.map(s=>s.value))),[V,pe]=X("team","q","",xe),[z,ie]=X("team","col","all",xe),[P,ae]=X("team","member",_,xe),[ge,fa]=X("team","zoom","week",Ye(...Qe)),[ja,De]=X("team","expanded",[],Va),ka=d.useCallback(s=>{De(x=>x.includes(s)?x.filter(w=>w!==s):[...x,s])},[De]),Me=he==="timeline",F=he==="projects",Ee=d.useRef(Date.now()).current;d.useEffect(()=>{var w,E;let s=!0;const x=(E=(w=D).authStatus)==null?void 0:E.call(w);return x==null||x.then(O=>{var R;s&&K(((R=O.user)==null?void 0:R.email)??null)}).catch(()=>{s&&K(null)}),()=>{s=!1}},[]);const G=d.useMemo(()=>z==="all"?Z:Z.filter(s=>s.key===z),[z]),be=G.map(s=>s.key).join(","),fe=F||t==="all"?void 0:t,re=d.useMemo(()=>{if(!I)return null;const s=Ka(I);return i.some(x=>x.id===s)?s:null},[I,i]),oe=P===_?re??void 0:P===H?void 0:P,$e=P!==_&&P!==H,Q=d.useMemo(()=>({projectId:fe,memberId:oe,q:V.trim()||void 0}),[fe,oe,V]),ce=d.useRef(!1),te=d.useCallback((s=!1)=>{!s&&!ce.current&&j("loading");const x=be?be.split(","):[];Promise.all(x.map(w=>D.listTasks({...Q,status:w,page:1,limit:la}))).then(w=>{u(E=>{const O={...E};return x.forEach((R,ne)=>{O[R]=w[ne].items}),O}),p(E=>{const O={...E};return x.forEach((R,ne)=>{O[R]=w[ne].total}),O}),ce.current=!0,h(!1),j("ready")}).catch(()=>{if(!ce.current){j("error");return}h(!0)})},[Q,be]);d.useEffect(()=>{te()},[te]);const Le=d.useCallback(()=>{D.listMembers().then(s=>{b(s.items),k("")}).catch(s=>k(za(s,"tidak diketahui")))},[]);d.useEffect(()=>{Le()},[Le]);const[Oe,xa]=d.useState(()=>V.trim());d.useEffect(()=>{const s=setTimeout(()=>xa(V.trim()),Lt);return()=>clearTimeout(s)},[V]);const ya=d.useCallback((s,x,w)=>{u(E=>({...E,[s]:x})),p(E=>({...E,[s]:w})),ce.current=!0,h(!1),j("ready")},[]),va=d.useMemo(()=>({projectId:Q.projectId,memberId:Q.memberId,q:Oe||void 0,page:1,limit:la}),[Q.projectId,Q.memberId,Oe]),de=d.useCallback(()=>te(!0),[te]);async function Sa(s,x){var O;const w=Xa(o,s.id,s.status,x);if(!w)return;const E=o;u(w.board);try{await D.patchTask(s.id,w.patch);const R=((O=Z.find(ne=>ne.key===x))==null?void 0:O.label)??x;le(`Tugas dipindah ke ${R}`,"ok",void 0,{action:{label:"Urungkan",onAction:()=>{Pe(s.id,{status:s.status})}}})}catch{u(E),l("Gagal memindahkan tugas","err","x-circle")}}async function Ca(s,x){var E;const w=o;u(ye(o,{...s,memberId:x}));try{await D.patchTask(s.id,{memberId:x});const O=x?((E=i.find(R=>R.id===x))==null?void 0:E.name)??"anggota":null;le(O?`Ditugaskan ke ${O}`:"Penugasan dikosongkan","ok",void 0,{action:{label:"Urungkan",onAction:()=>{Pe(s.id,{memberId:s.memberId})}}})}catch{u(w),l("Gagal menugaskan","err","x-circle")}}async function Pe(s,x){try{await D.patchTask(s,x),de()}catch{l("Gagal mengurungkan perubahan","err","x-circle")}}async function Na(s){const x=o;u(ye(o,{...s,specId:null,spec:null}));try{await D.unlinkTaskSpec(s.id),l("Tautan backlog dilepas","ok","unlink")}catch{u(x),l("Gagal melepas tautan","err","x-circle")}}const Be=G.every(s=>o[s.key].length===0),je=V.trim()!=="",Ae=(!F&&t!=="all"?1:0)+(z!=="all"?1:0)+($e?1:0),Re=Ae>0||je||oe!==void 0,Ia=((Ke=e.find(s=>s.id===t))==null?void 0:Ke.name)??t,Ta=((ze=i.find(s=>s.id===P))==null?void 0:ze.name)??P,wa=((Ge=Z.find(s=>s.key===z))==null?void 0:Ge.label)??z,Da=()=>{F||n("all"),ie("all"),ae(_),pe("")},Ma=()=>{F||n("all"),ie("all"),ae(H),pe("")},_e=d.useMemo(()=>G.flatMap(s=>o[s.key]),[o,G]),Ue=G.reduce((s,x)=>s+Math.max(0,(f[x.key]??0)-o[x.key].length),0),Ea=G.reduce((s,x)=>s+(f[x.key]??0),0),Fe=[...!F&&t!=="all"?[{key:"project",label:`Project: ${Ia}`,onRemove:()=>n("all")}]:[],...z!=="all"?[{key:"col",label:`Kolom: ${wa}`,onRemove:()=>ie("all")}]:[],...$e?[{key:"member",label:`Anggota: ${Ta}`,onRemove:()=>ae(_)}]:[]],$a=[...re?[{value:_,label:"Saya"}]:[],{value:H,label:"Semua anggota"},...i.map(s=>({value:s.id,label:s.name}))],La=P===_&&!re?H:P,Oa=a.jsxs(Ga,{gap:3,children:[a.jsx($,{label:"Project",children:a.jsx(B,{size:"sm","aria-label":"Filter project",value:t,disabled:F,onChange:s=>n(s.target.value),options:[{value:"all",label:"Semua project"},...e.map(s=>({value:s.id,label:s.name}))]})}),F&&a.jsx("p",{"data-testid":"project-filter-note",className:"hn-tm-hint",children:"Mode ini melintasi semua project"}),a.jsx($,{label:"Anggota",children:a.jsx(B,{size:"sm","aria-label":"Filter anggota",value:La,disabled:!!m,onChange:s=>ae(s.target.value),options:$a})}),m&&a.jsxs("p",{role:"alert",className:"hn-tm-hint hn-tm-alert",children:["Anggota gagal dimuat: ",m]}),a.jsx($,{label:"Kolom",children:a.jsx(B,{size:"sm","aria-label":"Filter kolom",value:z,onChange:s=>ie(s.target.value),options:[{value:"all",label:"Semua kolom"},...Z.map(s=>({value:s.key,label:s.label}))]})}),(Me||F)&&a.jsx($,{label:"Zoom",children:a.jsx(B,{size:"sm","aria-label":"Zoom linimasa",value:ge,onChange:s=>fa(s.target.value),options:Qe.map(s=>({value:s,label:Ot[s]}))})})]});return a.jsxs("div",{className:"hn-tm-screen",children:[a.jsxs("section",{className:"hn-tm-toolbar",role:"region","aria-label":"Kontrol papan tim",children:[a.jsxs("div",{className:"hn-tm-switches",children:[a.jsx(Se,{variant:"pill",value:he,onChange:ba,tabs:ia,"aria-label":"Mode tampilan"}),re&&a.jsx(Se,{variant:"pill","aria-label":"Lensa tugas",value:P===H?H:P===_?_:"",onChange:s=>ae(s),tabs:[{value:_,label:"Saya"},{value:H,label:"Semua"}]}),a.jsxs("span",{className:"hn-tm-count",role:"status",title:C?"Server tak menjawab saat menyegarkan — angka ini dari muatan terakhir yang berhasil":void 0,children:[Ea," tugas",C?" · data lama":""]}),a.jsx(qa,{})]}),a.jsx(Ha,{label:"Penyaring tim",search:{value:V,onChange:pe,label:"Cari tugas",placeholder:"mis. halaman harga atau deploy"},chips:Fe,filters:Oa,filtersLabel:"Filter",onReset:Fe.length>0||je?Da:void 0,resetLabel:"Reset filter",actions:a.jsxs(a.Fragment,{children:[a.jsx(U,{size:"sm",leftIcon:"plus",onClick:()=>{M(null),g(!0)},children:"Tugas baru"}),a.jsx(Za,{onDone:de,onToast:l}),a.jsx(oa,{label:"Lainnya",items:[{key:"members",label:"Anggota tim",icon:"users",onSelect:()=>c(!0)}]})]})})]}),G.map(s=>a.jsx(Bt,{status:s.key,params:va,onData:ya,refetch:de},s.key)),S==="loading"?a.jsx(W,{kind:"loading"}):S==="error"?a.jsx(W,{kind:"error",hint:"Gagal memuat papan tim.",action:()=>te(),actionLabel:"Coba lagi"}):Be&&!Re?a.jsx(W,{kind:"empty",icon:"users",title:"Papan tim masih kosong",hint:"Catat pekerjaan manusia di sekitar sesi agen — desain, meeting klien, deploy, nego.",action:()=>{M(null),g(!0)},actionLabel:"Tugas baru",actionIcon:"plus"}):a.jsxs(a.Fragment,{children:[Be&&Re&&a.jsx(W,{kind:"empty",compact:!0,icon:"filter",title:oe!==void 0&&Ae===0&&!je?"Tak ada tugas untuk kamu":"Tak ada tugas yang cocok dengan filter",hint:"Penyaring yang aktif menyembunyikan semua tugas di papan ini.",action:Ma,actionLabel:"Tampilkan semua",actionIcon:"x"}),F?a.jsx(Nt,{tasks:_e,projects:e,members:i,zoom:ge,today:Ee,hidden:Ue,expanded:ja,onToggle:ka,onOpen:s=>{M(s),g(!0)}}):Me?a.jsx(vt,{tasks:_e,members:i,zoom:ge,today:Ee,hidden:Ue,onOpen:s=>{M(s),g(!0)}}):a.jsx(kt,{board:o,totals:f,columns:G,members:i,projects:e,onOpenSpec:r,onMove:Sa,onAssign:Ca,onEscalate:L,onUnlink:Na,onOpen:s=>{M(s),g(!0)}})]}),a.jsx(Tt,{open:A,task:N,projects:e,members:i,defaultProjectId:fe??null,orderFor:s=>da(o[s]),onClose:()=>{g(!1),M(null)},onSaved:de,onToast:l}),y&&a.jsx(Dt,{task:y,projects:e,onClose:()=>L(null),onDone:s=>u(x=>ye(x,s)),onToast:l}),a.jsx(Et,{open:T,onClose:()=>c(!1),onChanged:b,onToast:l}),a.jsx(Ya,{toast:v})]})}export{ia as TEAM_VIEWS,Kt as TeamScreen};
@@ -0,0 +1,2 @@
1
+ import{h as $,i as te,j as t,M as se,f as It,g as ee,a3 as jn,a4 as Sa,m as Fe,n as yt,I as Me,a2 as yn,Z as wn,B as _,a5 as Sn,C as et,a6 as aa,a7 as na,a8 as ia,e as he,a9 as Nn,aa as In,ab as Cn,ac as Rn,ad as Tn,ae as En,af as An,ag as Pe,ah as Na,ai as $e,aj as zn,r as Dn,a1 as Fn,Y as xe,O as Ce,ak as Mn,al as sa,am as $n,an as wt,ao as Pn,q as ke,ap as Ia,b as Ln,aq as Bn,d as On,ar as Kn,p as _n,as as Gn,at as ra,au as Wn,o as kt,av as Un,aw as qn,c as Hn,ax as Vn,ay as la,az as Yn,aA as Jn,V as Xn,aB as Zn,aC as Qn,aD as Xe,aE as Ca,aF as Ct,aG as ei,aH as ti,D as ai,aI as ni,aJ as oa,aK as ii}from"./index-C4Py9MJV.js";import{R as o,r as O}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import{A as si}from"./fields-BY7SYerd.js";import"./xterm-3VOAfa_q.js";function Rt(e){return e.endedAt?e.endedReason==="reconciled"?"interrupted":e.exitCode===null||e.exitCode===0?"completed":"failed":"running"}const Ze=new Set;let De;function ri(e){return Ze.add(e),De||(De=setInterval(()=>{for(const n of[...Ze])n()},1e3)),()=>{Ze.delete(e),Ze.size===0&&De&&(clearInterval(De),De=void 0)}}const ca=20;function li(e,n){if(!n)return"—";const s=new Date(n).getTime()-new Date(e).getTime();if(!Number.isFinite(s)||s<0)return"—";const r=Math.round(s/1e3);if(r<60)return`${r} dtk`;const l=Math.round(r/60);return l<60?`${l} mnt`:`${Math.floor(l/60)} jam ${l%60} mnt`}function oi(e){switch(Rt(e)){case"running":return{label:"berjalan",tone:"neutral"};case"interrupted":return{label:"terputus",tone:"warn"};case"failed":return{label:`exit ${e.exitCode}`,tone:"err"};default:return{label:"selesai",tone:"ok"}}}const Ra=e=>Rt(e)==="interrupted"?"—":li(e.startedAt,e.endedAt),Ta=e=>Sa[e]??e;function ci({projects:e,onClose:n,onRestart:s}){const[r,l]=o.useState([]),[u,k]=o.useState(0),[g,C]=o.useState(1),[v,p]=o.useState(!1),[S,h]=o.useState(""),[x,N]=o.useState(""),[A,E]=o.useState(""),[T,y]=o.useState(""),[f,D]=o.useState(null),[K,V]=o.useState(null),[b,R]=o.useState(0);o.useEffect(()=>{const m=setTimeout(()=>y(A.trim()),250);return()=>clearTimeout(m)},[A]),o.useEffect(()=>{C(1)},[S,x,T]),o.useEffect(()=>{let m=!0;return p(!0),$.listSessionHistory({projectId:S||void 0,kind:x||void 0,q:T||void 0,page:g,limit:ca}).then(M=>{m&&(V(null),k(M.total),l(M.items))}).catch(M=>{m&&(l([]),k(0),V(te("memuat riwayat sesi",M)))}).finally(()=>{m&&p(!1)}),()=>{m=!1}},[S,x,T,g,b]);const F=wn(u,g,ca),w=m=>{var M;return((M=e.find(ae=>ae.id===m))==null?void 0:M.name)??m};return t.jsxs(se,{open:!0,title:"Riwayat sesi",icon:"history",onClose:n,width:900,children:[t.jsxs("div",{className:"hn-terminal-hist-toolbar",children:[t.jsx(It,{size:"sm",leftIcon:"search",placeholder:"mis. spec-412 atau reverse","aria-label":"Cari riwayat sesi",value:A,onChange:m=>E(m.target.value),className:"hn-terminal-hist-search"}),t.jsx(ee,{size:"sm","aria-label":"Filter project",value:S,onChange:m=>h(m.target.value),options:[{value:"",label:"Semua project"}].concat(e.map(m=>({value:m.id,label:m.name})))}),t.jsx(ee,{size:"sm","aria-label":"Filter jenis",value:x,onChange:m=>N(m.target.value),options:[{value:"",label:"Semua jenis"}].concat(jn.map(m=>({value:m,label:Sa[m]})))})]}),K?t.jsx(Fe,{kind:"error",icon:"history",title:"Riwayat belum bisa dimuat",hint:K,action:()=>R(m=>m+1),actionLabel:"Coba lagi"}):r.length===0&&!v?t.jsx(Fe,{kind:"empty",icon:"history",title:"Belum ada riwayat sesi",hint:"Riwayat terisi sendiri saat sesi terminal dibuka lalu ditutup — termasuk sesi backlog, terminal biasa, dan sesi project-level."}):t.jsxs("div",{className:"hn-terminal-hist-list",children:[r.map(m=>{const M=oi(m);return t.jsx("button",{onClick:()=>D(m),className:"hn-terminal-hist-row",children:t.jsxs("span",{className:"hn-dense-row hn-picker-row hn-terminal-hist-main",children:[t.jsx("span",{className:"hn-terminal-hist-when",children:new Date(m.startedAt).toLocaleString("id-ID")}),t.jsx(yt,{size:"sm",tone:"neutral",children:Ta(m.kind)}),t.jsx("span",{className:"hn-picker-title hn-terminal-hist-title",children:m.title??m.specId??w(m.projectId)}),m.transcriptBytes!==null&&t.jsx(Me,{name:"file-text",size:12,color:"var(--text-subtle)"}),t.jsx("span",{className:"hn-terminal-hist-duration",children:Ra(m)}),t.jsx(yt,{size:"sm",tone:M.tone,children:M.label})]})},m.id)}),v&&t.jsx("div",{className:"hn-terminal-hist-loading",children:"memuat…"})]}),t.jsx(yn,{page:F.page,pageCount:F.pageCount,total:u,from:F.from,to:F.to,onPage:C,unit:"sesi"}),f&&t.jsx(ui,{row:f,projectName:w(f.projectId),onBack:()=>D(null),onRestart:s})]})}function ui({row:e,projectName:n,onBack:s,onRestart:r}){const[l,u]=o.useState(null),[k,g]=o.useState("idle"),[C,v]=o.useState(null);async function p(x){try{if(!navigator.clipboard)throw new Error("clipboard tidak tersedia di browser ini");await navigator.clipboard.writeText(x),v({tone:"ok",text:"Transkrip disalin."})}catch(N){v({tone:"err",text:te("menyalin transkrip",N)})}}o.useEffect(()=>{if(e.transcriptBytes===null){g("none"),u(null);return}let x=!0;return g("loading"),$.sessionTranscript(e.id).then(N=>{x&&(u(N.text),g("idle"))}).catch(()=>{x&&(u(null),g("error"))}),()=>{x=!1}},[e.id,e.transcriptBytes]);const S=Rt(e)==="interrupted",h=[["Project",n],["Sesi",e.sessionId],["Jenis",Ta(e.kind)],["Agen",[e.agent,e.model,e.effort].filter(Boolean).join(" · ")],["Mulai",new Date(e.startedAt).toLocaleString("id-ID")],[S?"Terakhir terlihat hidup":"Selesai",e.endedAt?new Date(e.endedAt).toLocaleString("id-ID"):"berjalan"],...S&&e.reconciledAt?[["Terdeteksi mati",new Date(e.reconciledAt).toLocaleString("id-ID")]]:[],["Durasi",Ra(e)],["Direktori",e.cwd]];return e.specId&&h.splice(1,0,["Backlog",`${e.specId}${e.title?` · ${e.title}`:""}`]),e.branch&&h.push(["Branch",e.branch]),t.jsxs(se,{open:!0,title:e.title??e.specId??e.sessionId,icon:"history",onClose:s,width:1e3,children:[t.jsxs("div",{className:"hn-terminal-hist-actions",children:[t.jsx(_,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:s,children:"Kembali"}),t.jsx("div",{className:"hn-terminal-hist-spacer"}),l&&t.jsx(_,{size:"sm",variant:"secondary",leftIcon:"copy",onClick:()=>void p(l),children:"Salin transkrip"}),Sn(e.kind)&&t.jsx(_,{size:"sm",leftIcon:"play",onClick:()=>r(e),children:"Mulai lagi"})]}),S&&t.jsxs(et,{tone:"warn",title:"Sesi terputus — hasilnya tak diketahui",className:"hn-terminal-notice",children:["Panenya sudah lenyap saat hanoman menyala lagi (reboot, ",t.jsx("code",{children:"tmux kill-server"}),", atau host mati), jadi sesi ini tak meninggalkan exit code dan transkripnya kemungkinan besar tak sempat diambil — capture berjalan tepat sebelum pane dibunuh, dan di jalur ini sudah tak ada pane untuk dibaca. Periksa worktree & branch sesi ini sebelum menganggapnya selesai, lalu mulai lagi bila pekerjaannya belum tuntas."]}),t.jsx("div",{className:"hn-terminal-hist-meta",children:h.map(([x,N])=>t.jsxs(o.Fragment,{children:[t.jsx("span",{className:"hn-terminal-hist-key",children:x}),t.jsx("span",{className:"hn-terminal-hist-val",children:N})]},x))}),k==="loading"&&t.jsx("div",{className:"hn-terminal-hist-note",children:"memuat transkrip…"}),k==="none"&&t.jsx("div",{className:"hn-terminal-hist-note",children:S?"Tanpa transkrip — panenya sudah lenyap sebelum hanoman sempat mengambilnya.":"Tanpa transkrip — sesi ini ditutup sebelum fitur riwayat ada, atau panenya tak menyisakan keluaran."}),C&&t.jsx("div",{role:"status",className:C.tone==="err"?"hn-terminal-hist-copy is-err":"hn-terminal-hist-copy",children:C.text}),k==="error"&&t.jsx("div",{className:"hn-terminal-hist-error",children:"Transkrip tak terbaca lagi di server."}),l!==null&&t.jsx("pre",{className:"hn-terminal-hist-pre",children:l})]})}function di({open:e,projectId:n,projectName:s,projects:r,onProjectChange:l,onClose:u,onCreated:k}){var Z;const[g,C]=o.useState("claude"),[v,p]=o.useState("sonnet"),[S,h]=o.useState("medium"),[x,N]=o.useState({claude:{model:"sonnet",effort:"medium"},codex:{...na},antigravity:{...aa}}),[A,E]=o.useState(!1),[T,y]=o.useState(null),[f,D]=o.useState(null),[K,V]=o.useState(null),[b,R]=o.useState(!1),[F,w]=o.useState(""),[m,M]=o.useState([]),[ae,G]=o.useState(null);o.useEffect(()=>{e&&(y(null),D(null),$.getSettings().then(j=>{const L={claude:{model:j.model,effort:j.effort},codex:{...na,...j.codex??{}},antigravity:{...aa,...j.antigravity??{}}},U=j.agent??"claude",B=ia(L,U);N(L),C(U),p(B.model),h(B.effort)}).catch(j=>{y(`${te("memuat pengaturan",j)} · memakai default bawaan`)}),$.getCodexVersion().then(j=>V(j.version)).catch(j=>{y(L=>(L?`${L} · `:"")+te("membaca versi Codex CLI",j))}))},[e]),o.useEffect(()=>{if(!e||!b||!n)return;let j=!0;return G(null),$.listBranches(n).then(L=>{if(!j)return;const U=[...new Set([...L.branches,...L.remotes])].sort();M(U.map(B=>({value:B,label:L.branches.includes(B)?B:`${B} · origin`}))),w(B=>B&&!U.includes(B)?"":B)}).catch(L=>{j&&(M([]),w(""),G(te("memuat daftar branch",L)))}),()=>{j=!1}},[e,b,n]);const ce=j=>{C(j);const L=ia(x,j);p(L.model),h(L.effort)},je=j=>{p(j),h(L=>An(g,j,L))};async function pe(){E(!0),D(null);try{const{id:j}=await $.createTerminal(n,{agent:g,model:v,effort:S,...b?{worktree:!0,...F?{branchFrom:F}:{}}:{}});k(j),u()}catch(j){D(te("membuka sesi",j))}finally{E(!1)}}return t.jsxs(se,{open:e,onClose:u,icon:"plus",eyebrow:s,title:"Sesi baru",footer:t.jsxs(t.Fragment,{children:[t.jsx(_,{variant:"ghost",onClick:u,children:"Batal"}),t.jsx(_,{leftIcon:"play",disabled:A,onClick:()=>void pe(),children:"Buka sesi"})]}),children:[T&&t.jsx(et,{tone:"warn",title:"Pengaturan belum terbaca",className:"hn-terminal-notice",children:T}),f&&t.jsx(et,{tone:"err",title:"Sesi belum terbuka",className:"hn-terminal-notice",children:f}),t.jsxs("div",{className:"hn-terminal-intro",children:["Runtime untuk sesi ini. Default dari setelan global; ubah bila perlu. Sesi lahir dengan pilihan ini untuk seluruh hidupnya — ",t.jsx("code",{children:"/model"})," di terminal tetap bisa mengubahnya."]}),r&&l&&r.length>1&&t.jsx(he,{label:"Project",hint:"Direktori repo tempat sesi dibuka.",children:t.jsx(ee,{"aria-label":"Project",value:n,className:"hn-terminal-field-full",options:r.map(j=>({value:j.id,label:j.name})),onChange:j=>l(j.target.value)})}),t.jsx(he,{label:"Agen",hint:"Mesin yang menjalankan sesi ini. Perilaku sesi sama; hanya CLI-nya berbeda.",children:t.jsx(ee,{"aria-label":"Agen",value:g,className:"hn-terminal-field-full",options:Nn,onChange:j=>ce(j.target.value)})}),t.jsx(he,{label:"Model",children:t.jsx(ee,{"aria-label":"Model",value:v,className:"hn-terminal-field-full",options:In(g,v),onChange:j=>je(j.target.value)})}),t.jsx(he,{label:"Effort",children:t.jsx(ee,{"aria-label":"Effort",value:S,className:"hn-terminal-field-full",options:Cn(g,v).map(j=>({value:j,label:j})),onChange:j=>h(j.target.value)})}),t.jsx(he,{label:"Lokasi kerja",hint:b?t.jsxs(t.Fragment,{children:["Sesi bekerja di ",t.jsx("code",{children:".worktrees/term-…"})," pada branch baru ",t.jsx("code",{children:"term/…"}),"; commit-nya tetap ada setelah sesi ditutup."]}):"Sesi bekerja langsung di checkout project, berbagi berkas dengan sesi lain di sana.",children:t.jsx(Rn,{"aria-label":"Worktree terpisah",checked:b,label:"Worktree terpisah",onChange:()=>R(!b)})}),b&&t.jsx(he,{label:"Branch asal",hint:ae??"Worktree bercabang dari sini.",children:t.jsx(ee,{"aria-label":"Branch asal",value:F,className:"hn-terminal-field-full",options:[{value:"",label:"HEAD checkout project"},...m],onChange:j=>w(j.target.value)})}),g==="antigravity"&&t.jsx(si,{}),g==="codex"&&Tn(v,K)&&t.jsxs("div",{"data-testid":"codex-version-note",className:"hn-terminal-codex-note",children:["Codex CLI terpasang ",t.jsx("b",{children:K}),", sedangkan ",t.jsx("b",{children:v})," butuh ",t.jsx("b",{children:(Z=En(v))==null?void 0:Z.minClient}),". Sesi tetap boleh dijalankan, tapi modelnya belum tentu dikenali CLI ini."]})]})}function mi({projectId:e,projects:n,onProjectChange:s,onClose:r,onConfirm:l}){return t.jsx(se,{open:!0,onClose:r,icon:"terminal",title:"Terminal biasa",footer:t.jsxs(t.Fragment,{children:[t.jsx(_,{variant:"ghost",onClick:r,children:"Batal"}),t.jsx(_,{leftIcon:"play",disabled:!e,onClick:()=>l(e),children:"Buka terminal"})]}),children:t.jsx(he,{label:"Project",hint:"Shell dibuka di direktori repo project ini.",children:t.jsx(ee,{"aria-label":"Project",value:e,className:"hn-terminal-field-full",options:n.map(u=>({value:u.id,label:u.name})),onChange:u=>s(u.target.value)})})})}const Ea=()=>({rows:1,cols:1,cells:[null]}),Aa=(e,n)=>[...e.slice(0,n),...e.slice(n+1)],ua=e=>({...e,rows:e.rows+1,cells:[...e.cells,...Array(e.cols).fill(null)],...e.rowSizes?{rowSizes:[...e.rowSizes,1]}:{}});function da(e){const n=e.cols+1,s=[];for(let r=0;r<e.rows;r++)for(let l=0;l<n;l++)s.push(l<e.cols?e.cells[r*e.cols+l]??null:null);return{...e,cols:n,cells:s,...e.colSizes?{colSizes:[...e.colSizes,1]}:{}}}function ma(e,n){if(e.rows===1||n<0||n>=e.rows)return e;const s=[...e.cells];return s.splice(n*e.cols,e.cols),{...e,rows:e.rows-1,cells:s,...e.rowSizes?{rowSizes:Aa(e.rowSizes,n)}:{}}}function ha(e,n){if(e.cols===1||n<0||n>=e.cols)return e;const s=e.cols-1,r=[];for(let l=0;l<e.rows;l++)for(let u=0;u<e.cols;u++)u!==n&&r.push(e.cells[l*e.cols+u]??null);return{...e,cols:s,cells:r,...e.colSizes?{colSizes:Aa(e.colSizes,n)}:{}}}const za=.3,hi=(e,n,s)=>Math.min(s,Math.max(n,e));function Tt(e,n,s){if(n<0||n+1>=e.length||s===0)return e;const l=e.reduce((C,v)=>C+v,0)/e.length*za,u=e[n]+e[n+1],k=hi(e[n]+s,l,u-l);if(k===e[n])return e;const g=[...e];return g[n]=k,g[n+1]=u-k,g}function Da(e,n,s){const r=e.colSizes??Array(e.cols).fill(1),l=Tt(r,n,s);return l===r?e:{...e,colSizes:l}}function Fa(e,n,s){const r=e.rowSizes??Array(e.rows).fill(1),l=Tt(r,n,s);return l===r?e:{...e,rowSizes:l}}const pi=.05,fi=.15,Ma=(e,n)=>e.reduce((s,r)=>s+r,0)*(n?fi:pi);function gi(e,n,s,r=!1){const l=e.colSizes??Array(e.cols).fill(1);return Da(e,n,s*Ma(l,r))}function bi(e,n,s,r=!1){const l=e.rowSizes??Array(e.rows).fill(1);return Fa(e,n,s*Ma(l,r))}function pa(e,n){const r=e.reduce((k,g)=>k+g,0)/e.length*za,l=e[n]+e[n+1],u=Math.round(r/l*100);return{now:Math.round(e[n]/l*100),min:u,max:100-u}}function St(e,n,s){if(n<0||n>=e.cells.length)return e;const r=e.cells.map(l=>s!==null&&l===s?null:l);return r[n]=s,{...e,cells:r}}const ki=(e,n)=>({...e,cells:e.cells.map(s=>s&&n.has(s)?s:null)}),$a=e=>({id:crypto.randomUUID(),name:e,layout:Ea()});function fa(){const e=$a("Utama");return{groups:[e],active:e.id}}const Le=e=>e.groups.find(n=>n.id===e.active)??e.groups[0];function xi(e,n){const s=$a(n);return{groups:[...e.groups,s],active:s.id}}const vi=(e,n,s)=>({...e,groups:e.groups.map(r=>r.id===n?{...r,name:s}:r)});function ji(e,n){if(e.groups.length===1)return e;const s=e.groups.filter(r=>r.id!==n);return s.length===e.groups.length?e:{groups:s,active:e.active===n?s[0].id:e.active}}const yi=(e,n)=>e.groups.some(s=>s.id===n)?{...e,active:n}:e;function X(e,n){const s=Le(e);return{...e,groups:e.groups.map(r=>r.id===s.id?{...r,layout:n(r.layout)}:r)}}function Nt(e,n,s){const r=Le(e),l=s===null?e.groups:e.groups.map(u=>u.id===r.id?u:{...u,layout:St(u.layout,u.layout.cells.indexOf(s),null)});return{...e,groups:l.map(u=>u.id===r.id?{...u,layout:St(u.layout,n,s)}:u)}}function Ne(e,n){const s=Le(e).layout.cells.indexOf(null);return s===-1?e:Nt(e,s,n)}const wi=(e,n)=>({...e,groups:e.groups.map(s=>({...s,layout:St(s.layout,s.layout.cells.indexOf(n),null)}))}),ga=e=>new Set(e.groups.flatMap(n=>n.layout.cells.filter(s=>s!==null))),ba=(e,n)=>({...e,groups:e.groups.map(s=>({...s,layout:ki(s.layout,n)}))}),Pa="hanoman.terminal.workspace",La="hanoman.terminal.layout",Ie=e=>Pe.parse({version:1,groups:e.groups});function Qe(e,n){const s=e.groups,r=n&&s.some(l=>l.id===n)?n:s[0].id;return{groups:s,active:r}}function Si(e){try{const n=JSON.parse(e);if(!n||typeof n!="object")return null;const s=n,r=Pe.parse({version:1,groups:s.groups});return{workspace:r,active:typeof s.active=="string"&&r.groups.some(l=>l.id===s.active)?s.active:r.groups[0].id}}catch{return null}}function Ni(){try{const e=localStorage.getItem(Pa);if(e)return Si(e);const n=localStorage.getItem(La);if(!n)return null;const s=JSON.parse(n),r={id:crypto.randomUUID(),name:"Utama",layout:s};return{workspace:Pe.parse({version:1,groups:[r]}),active:r.id}}catch{return null}}function xt(){try{localStorage.removeItem(Pa),localStorage.removeItem(La)}catch{}}const Ba=e=>`hanoman.terminal.workspace.v2.${encodeURIComponent(e)}`;function Ii(e){try{const n=localStorage.getItem(Ba(e));if(!n)return null;const s=JSON.parse(n),r=Pe.parse(s.workspace);if(!Number.isInteger(s.revision)||(s.revision??-1)<0)return null;const l=typeof s.active=="string"&&r.groups.some(u=>u.id===s.active)?s.active:r.groups[0].id;return{workspace:r,revision:s.revision,active:l}}catch{return null}}function vt(e,n){try{const s=Pe.parse(n.workspace);if(!Number.isInteger(n.revision)||n.revision<0)return;const r=s.groups.some(l=>l.id===n.active)?n.active:s.groups[0].id;localStorage.setItem(Ba(e),JSON.stringify({workspace:s,revision:n.revision,active:r}))}catch{}}function jt(e){if(!(e instanceof $e)||e.status!==409)return null;const n=e.detail;if((n==null?void 0:n.code)!=="revision-conflict")return null;const s=zn.safeParse(n.current);return s.success?s.data:null}function Ci(e){const n=O.useRef(null);n.current||(n.current=fa());const[s,r]=O.useState(n.current),[l,u]=O.useState("loading"),[k,g]=O.useState(null),[C,v]=O.useState(!1),p=O.useRef(s),S=O.useRef(0),h=O.useRef(!1),x=O.useRef(Promise.resolve()),N=O.useRef(0),A=O.useCallback(b=>{p.current=b,r(b)},[]),E=O.useCallback(b=>{h.current=b,v(b)},[]),T=O.useCallback(b=>{const R=x.current.then(b,b);return x.current=R.then(()=>{},()=>{}),R},[]),y=O.useCallback((b,R="ready",F=null,w=p.current.active)=>{const m=b.workspace?Qe(b.workspace,w):fa();S.current=b.revision,A(m),u(R),g(F),E(!0),b.workspace&&vt(e,{workspace:b.workspace,revision:b.revision,active:m.active})},[A,E,e]),f=O.useCallback(b=>{const R=Ii(e);R&&(S.current=R.revision,A(Qe(R.workspace,R.active))),E(!1),u("recovering"),g(b instanceof Error?b.message:"Layout server belum tersambung")},[A,E,e]),D=O.useCallback(()=>T(async()=>{try{y(await $.getTerminalWorkspace())}catch(b){f(b)}}),[y,T,f]);O.useEffect(()=>{const b=++N.current;return u("loading"),g(null),E(!1),T(async()=>{try{const R=await $.getTerminalWorkspace();if(b!==N.current)return;if(R.workspace){y(R),xt();return}const F=Ni();if(!F){y(R);return}try{const w=await $.putTerminalWorkspace({baseRevision:R.revision,workspace:F.workspace});if(b!==N.current)return;A(Qe(w.workspace,F.active)),S.current=w.revision,vt(e,{workspace:w.workspace,revision:w.revision,active:F.active}),xt(),u("ready"),g(null),E(!0)}catch(w){const m=jt(w);m!=null&&m.workspace?(y(m,"conflict","Layout server lebih baru; layout lokal lama tidak diunggah"),xt()):f(w)}}catch(R){b===N.current&&f(R)}}),()=>{N.current+=1}},[y,T,f,A,E,e]),O.useEffect(()=>{const b=()=>{D()},R=()=>{document.visibilityState==="visible"&&D()};return window.addEventListener("focus",b),document.addEventListener("visibilitychange",R),()=>{window.removeEventListener("focus",b),document.removeEventListener("visibilitychange",R)}},[D]);const K=O.useCallback(b=>T(async()=>{if(!h.current)return!1;const R=b(p.current);let F,w;try{F=Ie(R),w=Ie(p.current)}catch{return u("conflict"),g("Layout tidak valid dan tidak disimpan"),!1}if(Na(F,w))return!0;try{return y(await $.putTerminalWorkspace({baseRevision:S.current,workspace:F}),"ready",null,R.active),!0}catch(m){const M=jt(m);if(!(M!=null&&M.workspace))return f(m),!1;const ae=b(Qe(M.workspace,p.current.active));try{const G=await $.putTerminalWorkspace({baseRevision:M.revision,workspace:Ie(ae)});return y(G,"conflict","Layout berubah di perangkat lain; perubahan ini diterapkan ulang",ae.active),!0}catch(G){if(!jt(G)&&!(G instanceof $e&&G.status===409))return f(G),!1;try{y(await $.getTerminalWorkspace(),"conflict","Layout berubah lagi di perangkat lain; state terbaru dimuat")}catch(ce){f(ce)}return!1}}}),[y,T,f]),V=O.useCallback(b=>{const R=yi(p.current,b);A(R);const F=Ie(R);vt(e,{workspace:F,revision:S.current,active:R.active})},[A,e]);return{workspace:s,status:l,message:k,writable:C,mutate:K,setActive:V,refresh:D}}const Ri=Dn("focus","grid"),ka={attention:0,running:1,open:1,failed:2,done:3};function Oa(e,n){return e.exited?e.exitCode?{tone:"failed",label:`Gagal · exit ${e.exitCode}`}:{tone:"done",label:"Selesai"}:n?{tone:"done",label:"Selesai"}:e.deciding?{tone:"attention",label:"Lead memutuskan"}:e.decision?{tone:"attention",label:"Menunggu keputusan"}:e.specId?{tone:"running",label:"Berjalan"}:{tone:"open",label:"Terbuka"}}function Ti(e){const n=e.startedAt;return typeof n=="number"&&Number.isFinite(n)&&n>0?n*1e3:null}function Ei(e,n){const s=e.map((r,l)=>({session:r,index:l,rank:ka[Oa(r,n.has(r.id)).tone]}));return s.sort((r,l)=>{if(r.rank!==l.rank)return r.rank-l.rank;if(r.rank===ka.attention){const u=r.session.decisionAt?Date.parse(r.session.decisionAt):Number.NaN,k=l.session.decisionAt?Date.parse(l.session.decisionAt):Number.NaN,g=Number.isNaN(u)?Number.POSITIVE_INFINITY:u,C=Number.isNaN(k)?Number.POSITIVE_INFINITY:k;if(g!==C)return g<C?-1:1}return r.index-l.index}),s.map(r=>r.session)}function Ai(e){const n=new Map;for(const s of e){const r=n.get(s.projectId);r?r.push(s):n.set(s.projectId,[s])}return[...n.values()].flat()}function zi(e,n){if(n){const s=e.find(r=>r.id===n);if(s)return s}return e[0]??null}function Di(e,n,s){if(s<=0)return null;const r=e<0?0:e;switch(n){case"ArrowDown":return Math.min(r+1,s-1);case"ArrowUp":return Math.max(r-1,0);case"Home":return 0;case"End":return s-1;default:return null}}const Ka={attention:"awaiting",running:"running",open:"idle",failed:"failed",done:"done"};function Fi(e){const[n,s]=o.useState(()=>Date.now());return o.useEffect(()=>{const r=setInterval(()=>s(Date.now()),e);return()=>clearInterval(r)},[e]),n}function xa({items:e,focusedId:n,onFocus:s,menuFor:r,label:l="Daftar sesi"}){const u=Fi(3e4),k=o.useRef([]),g=new Set(e.map(p=>p.session.projectId)).size>1,C=e.findIndex(p=>p.session.id===n),v=p=>{var N;const S=k.current.indexOf(p.target);if(S<0)return;const h=Di(S,p.key,e.length);if(h===null)return;p.preventDefault();const x=e[h];x&&(s(x.session.id),(N=k.current[h])==null||N.focus())};return t.jsx("ul",{role:"list","aria-label":l,className:"hn-terminal-rail-list",onKeyDown:v,children:e.map((p,S)=>{var T;const{session:h,status:x}=p,N=h.id===n,A=N||C<0&&S===0,E=p.startedMs!==null?Fn(p.startedMs,u):"";return t.jsxs(o.Fragment,{children:[g&&p.session.projectId!==((T=e[S-1])==null?void 0:T.session.projectId)&&t.jsx("li",{role:"presentation",className:"hn-terminal-rail-group",children:p.projectName}),t.jsx("li",{className:"hn-terminal-rail-item",children:t.jsxs("div",{className:`hn-terminal-rail-row${N?" is-focused":""}`,"data-tone":x.tone,children:[t.jsxs("button",{type:"button",className:"hn-terminal-rail-main",ref:y=>{k.current[S]=y},tabIndex:A?0:-1,"aria-current":N?"true":void 0,title:p.label,onClick:()=>s(h.id),children:[t.jsx("span",{className:"hn-terminal-rail-name",children:p.label}),t.jsxs("span",{className:"hn-terminal-rail-meta",children:[t.jsx(xe,{status:Ka[x.tone],variant:"dot",size:"sm",children:x.label}),E&&t.jsx("span",{className:"hn-terminal-rail-time",children:E})]})]}),t.jsx(Ce,{label:`Aksi sesi ${h.id} di daftar`,items:r(h)})]})})]},h.id)})})}const Mi=[],$i=e=>!!(e.binding??e.repoDir),Pi=e=>{var n;return((n=e.find($i)??e[0])==null?void 0:n.id)??""},Li=e=>e instanceof $e&&e.status===400&&typeof e.detail=="object"&&e.detail!==null&&e.detail.needsBind===!0;function es({userId:e="test-user",projects:n,backlog:s=Mi,focusSession:r,startedSession:l,onStartedSessionHandled:u,onStartBacklog:k,onOpenReview:g,onOpenSessionReview:C,titleOf:v,onIntegrate:p,onIntegrateSession:S,specOf:h,sessions:x,setSessions:N,onOpenProject:A}){const[E,T]=o.useState([]),y=x??E,f=N??T,[D,K]=o.useState([]),V=Ci(e),{workspace:b,status:R,message:F,writable:w,mutate:m,setActive:M,refresh:ae}=V,[G,ce]=ke("terminal","project",Pi(n),ai),je=Ia(),pe=Ln(),Z=pe==="mobile",[j,L]=ke("terminal","fontSize",je?Zn:Qn,Xn),[U,B]=ke("terminal","keys",je&&!Z,Xe),[re,tt]=ke("terminal","predict",!0,Xe),[Y,ye]=ke("terminal","diag",!1,Xe),[ue,Be]=ke("terminal","sr",!1,Xe),Re=a=>L(i=>Jn(i+a)),[fe,At]=o.useState(!1),[le,at]=o.useState(null),[Wa,Oe]=o.useState(!1),[Ua,Ke]=o.useState(null),[qa,zt]=o.useState(!1),[Ha,nt]=o.useState(!1),[Va,_e]=o.useState(!1),[Ya,it]=ke("terminal","view","focus",Ri),J=Ya==="focus",[st,Te]=o.useState(null),[rt,Ja]=o.useState(()=>new Set),[Xa,Za]=o.useState(null),[Dt,Ft]=o.useState(!1),[Qa,Mt]=o.useState(!1),[ge,Ee]=o.useState(null),[Ge,$t]=o.useState(!1),[We,Pt]=o.useState(null),lt=Bn(),{confirm:en,dialog:tn}=On(),z=Le(b).layout,ot=z.rows===1&&z.cols===1&&!z.cells[0]&&y.length===0,ct=o.useRef(null),[an,nn]=o.useState(Number.POSITIVE_INFINITY);o.useEffect(()=>{const a=ct.current;if(!a||typeof ResizeObserver!="function")return;const i=new ResizeObserver(c=>{var I;const d=((I=c[0])==null?void 0:I.contentRect.width)??a.getBoundingClientRect().width;d>0&&nn(d)});return i.observe(a),()=>i.disconnect()},[ot]);const sn=pe==="tablet"&&Kn(z.cols,an,Yn),W=Z||sn,[ne,Ue]=o.useState(0),[oe,qe]=o.useState(null),ut=o.useRef(null),Ae=a=>{Te(a),qe(a)},rn=o.useCallback((a,i)=>{Ja(c=>{if(c.has(a)===i)return c;const d=new Set(c);return i?d.add(a):d.delete(a),d})},[]),Lt=o.useMemo(()=>Ai(Ei(y,rt)),[y,rt]),He=zi(Lt,st),Ve=(He==null?void 0:He.id)??null;o.useEffect(()=>{Ve&&Ve!==st&&Te(Ve)},[Ve,st]);const[we,ln]=o.useState(!1),[Ye,Bt]=o.useState(null),[on,cn]=o.useState(0);o.useEffect(()=>{let a=!0;return $.listTerminals().then(i=>{a&&(Bt(null),f(i),ln(!0))}).catch(i=>{a&&Bt(te("memuat daftar sesi",i))}),()=>{a=!1}},[on]);const[un,de]=_n();o.useEffect(()=>Gn(a=>{a.t==="sessions"&&!x?f(a.sessions):a.t==="cleanups"&&K(a.cleanups)}),[]),o.useEffect(()=>{if(!we||!w)return;const a=new Set(y.map(c=>c.id)),i=ba(b,a);Na(Ie(i),Ie(b))||m(c=>ba(c,a))},[m,y,we,w,b]),o.useEffect(()=>{!l||l.specId==null||!we||(f(a=>a.some(i=>i.id===l.id)?a:[...a,{...l,cwd:"",exited:!1}]),Te(l.id),qe(l.id),u==null||u())},[u,we,l]);const dt=o.useRef(null);o.useEffect(()=>{if(!r){ut.current=null,dt.current=null;return}if(!(!we||ut.current===r)){if(!y.some(a=>a.id===r&&!a.exited)){if(dt.current===r)return;dt.current=r,$.listSessionHistory({q:r,limit:1}).then(a=>de(ra,"warn","history",a.total>0?{action:{label:Wn,onAction:()=>_e(!0)},duration:7e3}:void 0)).catch(()=>{de(ra,"warn","history")});return}ut.current=r,Te(r),qe(r)}},[r,y,we,de]),o.useEffect(()=>{if(!oe)return;const a=b.groups.find(i=>i.layout.cells.includes(oe));if(a){a.id!==b.active&&M(a.id);return}w&&m(i=>{if(ga(i).has(oe))return i;const c=Ne(i,oe);return c!==i||!W?c:Nt(i,ne,oe)})},[ne,W,m,oe,M,w,b]),o.useEffect(()=>{le&&!y.some(a=>a.id===le)&&at(null)},[le,y]);const mt=D.filter(a=>a.error),ie=a=>y.find(i=>i.id===a)??null,Q=o.useCallback(a=>{var i;return((i=n.find(c=>c.id===a))==null?void 0:i.name)??a},[n]);function dn(a){f(i=>i.some(c=>c.id===a)?i:[...i,{id:a,projectId:G,cwd:"",exited:!1}]),m(i=>Ne(i,a)),Ae(a)}async function Ot(a){if(!a)return;nt(!1);let i;try{({id:i}=await $.createShell(a))}catch(c){Li(c)?de(`Project ${Q(a)} belum terhubung ke folder repo — hubungkan dulu.`,"err","folder-git-2",A?{action:{label:"Buka project",onAction:()=>A(a)}}:void 0):de(te("membuka terminal biasa",c),"err","x-circle");return}f(c=>[...c,{id:i,projectId:a,cwd:"",exited:!1}]),m(c=>Ne(c,i)),Ae(i)}async function Kt(a,i){if(k&&!i){Oe(!1),Ke(null),k(a);return}const c=ti(a.source);try{const{id:d}=await $.startSession({spec:a.id,flow:c,...i?{force:i}:{}});f(I=>I.some(P=>P.id===d)?I:[...I,{id:d,projectId:a.projectId,specId:a.id,flow:c,cwd:"",exited:!1}]),m(I=>Ne(I,d)),Ae(d),Oe(!1),Ke(null)}catch(d){if(lt.offerRetry(d,a.id,P=>Kt(a,P)))return;const I=d instanceof $e&&(d.status===400||d.status===422);Ke(`${a.id} · gagal mulai${I?" · project belum punya repoDir":""}`)}}async function _t(a,i){try{const c=a.specId?await $.startSession({spec:a.specId,flow:a.flow??"feature",agent:a.agent==="antigravity"?"antigravity":a.agent==="codex"?"codex":"claude",...a.model?{model:a.model}:{},...a.effort?{effort:a.effort}:{},...i?{force:i}:{}}):a.kind==="shell"?await $.createShell(a.projectId):a.kind==="terminal"?await $.createTerminal(a.projectId,{agent:a.agent==="antigravity"?"antigravity":a.agent==="codex"?"codex":"claude",...a.model?{model:a.model}:{},...a.effort?{effort:a.effort}:{}}):await(i?$.createTerminalFlow(a.projectId,a.kind,{force:i}):$.createTerminalFlow(a.projectId,a.kind));f(d=>d.some(I=>I.id===c.id)?d:[...d,{id:c.id,projectId:a.projectId,specId:a.specId??void 0,cwd:"",exited:!1}]),m(d=>Ne(d,c.id)),Ae(c.id),_e(!1)}catch(c){if((a.specId||a.kind!=="shell"&&a.kind!=="terminal")&&lt.offerRetry(c,`${a.projectId} · ${a.title??a.specId??a.kind}`,d=>_t(a,d)))return}}const Gt=new Set(y.filter(a=>a.specId&&!a.exited).map(a=>a.specId)),mn=s.filter(a=>a.stage!=="done"&&!Gt.has(a.id));function Wt(a){f(i=>i.filter(c=>c.id!==a)),$.deleteTerminal(a).catch(i=>{i instanceof $e&&i.status===404||de(te(`menutup sesi ${a.slice(0,6)}`,i),"err","x-circle")})}async function Ut(){if(!ge||Ge)return;const{id:a,value:i}=ge;$t(!0);try{const c=await $.renameTerminal(a,i);f(d=>d.map(I=>{if(I.id!==a)return I;const{name:P,...H}=I;return c.name?{...H,name:c.name}:H})),Ee(null),de(c.name?"Nama sesi disimpan":"Nama kustom dihapus","ok")}catch(c){de(te("mengganti nama sesi",c),"err","x-circle")}finally{$t(!1)}}async function ht(a){const i=ie(a),c=`${i?ve(i,Q,v):a} · ${a.slice(0,6)}`,d=!!i&&!i.exited;await en({title:`Tutup sesi "${c}"?`,impact:[d?"Agen yang sedang berjalan di sesi ini akan dihentikan.":"Sesi ini sudah berhenti, jadi tidak ada agen yang perlu dihentikan.","Worktree sesi ini ikut dibersihkan dari disk."],confirmLabel:"Tutup sesi",icon:"square",tone:"danger"})&&Wt(a)}const hn=o.useCallback((a,i)=>{f(c=>c.map(d=>d.id===a?{...d,exited:!0,exitCode:i}:d))},[]),qt={killSession:Wt,requestKill:ht,detach:a=>{m(i=>wi(i,a))},markExited:hn,setFullId:at,openDialog:(a,i)=>Pt({kind:a,sessionId:i}),openRename:a=>{var i;return Ee({id:a,value:((i=ie(a))==null?void 0:i.name)??""})},props:{onOpenReview:g,onOpenSessionReview:C,titleOf:v,onIntegrate:p,onIntegrateSession:S,specOf:h}},q=o.useRef(qt);q.current=qt;const Ht=o.useRef(new Map),be=a=>{let i=Ht.current.get(a);return i||(i={onClose:()=>void q.current.requestKill(a),onForget:()=>q.current.killSession(a),onDetach:()=>q.current.detach(a),onExit:c=>q.current.markExited(a,c),onFullscreen:()=>q.current.setFullId(a),onDialog:c=>q.current.openDialog(c,a),onRename:()=>q.current.openRename(a)},Ht.current.set(a,i)),i},Vt=o.useRef(new Map),pn=a=>{let i=Vt.current.get(a);return i||(i=(c,d)=>{Za({sessionId:a,phases:c}),rn(a,d)},Vt.current.set(a,i)),i},fn=a=>Ga(a,{label:ve(a,Q,v),canArrange:w,specOf:h,onReview:g,onSessionReview:C,onIntegrate:p,onIntegrateSession:S,onDialog:be(a.id).onDialog,onDetach:be(a.id).onDetach,onFullscreen:be(a.id).onFullscreen,onKill:()=>void ht(a.id),onRename:be(a.id).onRename}),Se=o.useRef({onOpenReview:a=>{var i,c;return(c=(i=q.current.props).onOpenReview)==null?void 0:c.call(i,a)},onOpenSessionReview:(a,i)=>{var c,d;return(d=(c=q.current.props).onOpenSessionReview)==null?void 0:d.call(c,a,i)},titleOf:a=>{var i,c;return(c=(i=q.current.props).titleOf)==null?void 0:c.call(i,a)},onIntegrate:(a,i,c)=>{var d,I;return(I=(d=q.current.props).onIntegrate)==null?void 0:I.call(d,a,i,c)},onIntegrateSession:(a,i,c)=>{var d,I;return(I=(d=q.current.props).onIntegrateSession)==null?void 0:I.call(d,a,i,c)},specOf:a=>{var i,c;return(c=(i=q.current.props).specOf)==null?void 0:c.call(i,a)}}).current,gn=(a,i)=>{Ue(a),m(c=>Nt(c,a,i))},bn=a=>{Ae(a),m(i=>Ne(i,a))},kn=ga(b),pt=y.filter(a=>!kn.has(a.id));o.useEffect(()=>{if(!oe)return;const a=z.cells.indexOf(oe);a<0||(Ue(a),qe(null))},[z.cells,oe]),o.useEffect(()=>{ne>=z.cells.length&&Ue(Math.max(0,z.cells.length-1))},[ne,z.cells.length]);const Je=o.useRef(null),[me,ft]=o.useState(null),gt=(me==null?void 0:me.axis)==="col"?me.sizes:z.colSizes??Array(z.cols).fill(1),bt=(me==null?void 0:me.axis)==="row"?me.sizes:z.rowSizes??Array(z.rows).fill(1);function Yt(a,i,c){var P,H,ze;if(!w)return;const d=(P=ct.current)==null?void 0:P.getBoundingClientRect();if(!d)return;(ze=(H=c.currentTarget).setPointerCapture)==null||ze.call(H,c.pointerId);const I=a==="col"?gt:bt;Je.current={axis:a,index:i,pointerId:c.pointerId,start:a==="col"?c.clientX:c.clientY,extent:a==="col"?d.width:d.height,startSizes:I,latest:I},ft({axis:a,sizes:I})}function Jt(a){const i=Je.current;if(!i||i.pointerId!==a.pointerId)return;const c=i.axis==="col"?a.clientX:a.clientY,d=i.startSizes.reduce((P,H)=>P+H,0),I=(c-i.start)/i.extent*d;i.latest=Tt(i.startSizes,i.index,I),ft({axis:i.axis,sizes:i.latest})}function Xt(a){var c,d;const i=Je.current;!i||i.pointerId!==a.pointerId||(Je.current=null,(d=(c=a.currentTarget).releasePointerCapture)==null||d.call(c,a.pointerId),ft(null),i.latest!==i.startSizes&&m(I=>X(I,P=>i.axis==="col"?{...P,colSizes:i.latest}:{...P,rowSizes:i.latest})))}function Zt(a,i,c){if(!w)return;const d=a==="col"?"ArrowRight":"ArrowDown",I=a==="col"?"ArrowLeft":"ArrowUp",P=c.key===d?1:c.key===I?-1:0;P!==0&&(c.preventDefault(),m(H=>X(H,ze=>a==="col"?gi(ze,i,P,c.shiftKey):bi(ze,i,P,c.shiftKey))))}function Qt(a,i){w&&m(c=>X(c,d=>{const I=a==="col"?d.colSizes??Array(d.cols).fill(1):d.rowSizes??Array(d.rows).fill(1),H=(I[i]+I[i+1])/2-I[i];return a==="col"?Da(d,i,H):Fa(d,i,H)}))}const ea=t.jsxs("div",{className:"hn-terminal-display",children:[t.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[t.jsx("span",{className:"hn-terminal-display-label",children:"Ukuran teks terminal"}),t.jsx(kt,{size:"sm",icon:"minus",label:"Perkecil teks terminal",disabled:j<=Un,onClick:()=>Re(-1)}),t.jsxs("span",{className:"hn-terminal-display-value",children:[j,"px"]}),t.jsx(kt,{size:"sm",icon:"plus",label:"Perbesar teks terminal",disabled:j>=qn,onClick:()=>Re(1)})]}),t.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[t.jsx("span",{className:"hn-terminal-display-label",children:"Papan tombol layar (Esc · panah · Enter)"}),t.jsx(_,{size:"sm",variant:"secondary","aria-pressed":U,onClick:()=>B(a=>!a),children:U?"Sembunyikan":"Tampilkan"})]}),t.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[t.jsx("span",{className:"hn-terminal-display-label",children:"Ketik responsif (huruf tampil sebelum echo server)"}),t.jsx(_,{size:"sm",variant:"secondary","aria-pressed":re,"aria-label":`${re?"Matikan":"Nyalakan"} ketik responsif`,onClick:()=>tt(a=>!a),children:re?"Matikan":"Nyalakan"})]}),t.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[t.jsx("span",{id:"terminal-sr-label",className:"hn-terminal-display-label",children:"Mode pembaca layar"}),t.jsx(_,{size:"sm",variant:"secondary","aria-pressed":ue,"aria-describedby":"terminal-sr-hint","aria-label":`${ue?"Matikan":"Nyalakan"} mode pembaca layar`,onClick:()=>Be(a=>!a),children:ue?"Matikan":"Nyalakan"})]}),t.jsx("p",{id:"terminal-sr-hint",className:"hn-terminal-sr-hint",children:"Untuk pembaca layar: teks terminal tersedia di DOM; kecepatan lebih rendah. Tab dikirim ke sesi (tidak memindahkan fokus). Untuk keluar dari terminal tekan Ctrl+Shift+Esc."}),!J&&t.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[t.jsx("span",{id:"terminal-reset-grid-hint",className:"hn-terminal-display-label",children:'Kembalikan grid ke 1 kolom × 1 baris (sesi lain pindah ke "belum di grid")'}),t.jsx(_,{size:"sm",variant:"secondary","aria-describedby":"terminal-reset-grid-hint",disabled:!w||z.cols===1&&z.rows===1,onClick:()=>void m(a=>X(a,()=>Ea())),children:"Reset grid"})]}),t.jsxs("details",{className:"hn-terminal-diag",children:[t.jsxs("summary",{className:"hn-terminal-diag-summary",children:["Diagnostik",Y?" · perekaman aktif":""]}),t.jsxs("div",{className:"hn-dense-row hn-terminal-display-row hn-terminal-diag-row",children:[t.jsx("span",{className:"hn-terminal-display-label",children:"Rekam jalur ketik — mencatat setiap tombol yang ditekan di pane. Nyalakan hanya saat menyelidiki masalah ketik."}),t.jsx(_,{size:"sm",variant:"secondary","aria-pressed":Y,"aria-label":`${Y?"Matikan":"Nyalakan"} rekam jalur ketik`,onClick:()=>ye(a=>!a),children:Y?"Matikan":"Nyalakan"})]})]})]}),ta=[{key:"backlog",label:"Ambil backlog",icon:"inbox",onSelect:()=>{Ke(null),Oe(!0)}},{key:"history",label:"Riwayat sesi",icon:"history",onSelect:()=>_e(!0)},{key:"shell",label:"Terminal biasa",icon:"terminal",onSelect:()=>n.length>1?nt(!0):void Ot(G)}],xn=[{key:"col+",label:"+ Kolom",icon:"columns-2",disabled:!w,onSelect:()=>void m(a=>X(a,da))},{key:"row+",label:"+ Baris",icon:"rows-2",disabled:!w,onSelect:()=>void m(a=>X(a,ua))},{key:"col-",label:"Hapus kolom aktif",icon:"columns-2",disabled:!w||z.cols===1,onSelect:()=>void m(a=>X(a,i=>ha(i,ne%i.cols)))},{key:"row-",label:"Hapus baris aktif",icon:"rows-2",disabled:!w||z.rows===1,onSelect:()=>void m(a=>X(a,i=>ma(i,Math.floor(ne/i.cols))))}],vn=[{key:"mode",label:J?"Pakai mode Grid":"Pakai mode Fokus",icon:J?"columns-2":"terminal",onSelect:()=>it(J?"grid":"focus")},{key:"full",label:fe?"Keluar layar penuh":"Layar penuh",icon:fe?"minimize-2":"maximize-2",onSelect:()=>At(a=>!a)},{key:"display",label:"Tampilan terminal",icon:"sliders",onSelect:()=>Mt(!0)}];return t.jsxs("div",{"data-testid":"terminal-root",className:fe?"hn-terminal-screen is-maxed":"hn-terminal-screen",children:[t.jsxs("div",{className:"hn-terminal-toolbar",role:"group","aria-label":"Terminal",children:[t.jsx(_,{size:"sm",leftIcon:"plus",title:"Pilih runtime lalu buka sesi agen di direktori project. Agen berjalan dengan izin penuh (claude --dangerously-skip-permissions).",onClick:()=>zt(!0),children:"Sesi baru"}),Z?t.jsxs(t.Fragment,{children:[t.jsx(wa,{compact:!0,items:ta}),J&&y.length>0&&t.jsxs("button",{type:"button",className:"hn-terminal-rail-toggle","aria-haspopup":"dialog","aria-expanded":Dt,onClick:()=>Ft(!0),children:["Sesi · ",y.length]}),t.jsx(Ce,{label:"Menu terminal",title:"Terminal",items:vn})]}):t.jsxs(t.Fragment,{children:[t.jsx(wa,{items:ta}),t.jsxs("div",{className:"hn-terminal-seg",role:"group","aria-label":"Mode tampilan terminal",children:[t.jsx("button",{type:"button",className:"hn-terminal-seg-btn","aria-pressed":J,title:"Satu terminal fokus dengan daftar sesi di samping",onClick:()=>it("focus"),children:"Fokus"}),t.jsx("button",{type:"button",className:"hn-terminal-seg-btn","aria-pressed":!J,title:"Beberapa terminal sekaligus dalam grid",onClick:()=>it("grid"),children:"Grid"})]}),t.jsx(Ce,{label:"Tampilan terminal",icon:"sliders",items:[],children:ea}),t.jsx(kt,{size:"sm",icon:fe?"minimize-2":"maximize-2",label:fe?"Keluar layar penuh":"Layar penuh","aria-pressed":fe,onClick:()=>At(a=>!a)})]})]}),(R!=="ready"||D.length>0)&&t.jsxs("div",{className:"hn-terminal-status",children:[R!=="ready"&&t.jsx("span",{"data-testid":"terminal-workspace-status",title:F??void 0,className:R==="conflict"?"hn-terminal-status-warn":void 0,children:R==="loading"?"Memuat layout server…":R==="recovering"?t.jsxs(t.Fragment,{children:[t.jsx("span",{children:"Layout server belum tersambung"})," ",t.jsx("button",{type:"button",onClick:()=>void ae(),children:"Coba lagi"})]}):F??"Layout berubah di perangkat lain"}),D.length>0&&t.jsx("span",{"data-testid":"worktree-cleanups",title:D.map(a=>`${a.sessionId}${a.error?` — ${a.error}`:""}`).join(`
2
+ `),className:mt.length?"hn-terminal-status-err":void 0,children:mt.length?`${mt.length} worktree gagal dibersihkan`:`membersihkan ${D.length} worktree…`})]}),!J&&t.jsxs("div",{className:"hn-terminal-grid-bar",children:[t.jsx(Oi,{compact:fe,ws:b,writable:w,onSelect:M,onAdd:()=>void m(a=>xi(a,`Grup ${a.groups.length+1}`)),onRename:(a,i)=>void m(c=>vi(c,a,i)),onRemove:a=>void m(i=>ji(i,a))}),!W&&t.jsxs(t.Fragment,{children:[t.jsx(_,{size:"sm",variant:"ghost",disabled:!w,onClick:()=>void m(a=>X(a,da)),children:"+ Kolom"}),t.jsx(_,{size:"sm",variant:"ghost",disabled:!w,onClick:()=>void m(a=>X(a,ua)),children:"+ Baris"})]}),W&&t.jsx(Ce,{label:"Atur grid",icon:"sliders",items:xn})]}),Ye&&t.jsxs(et,{tone:"err",title:"Daftar sesi belum bisa dimuat",className:"hn-terminal-notice--tight",children:[t.jsxs("span",{children:[Ye," "]}),t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>cn(a=>a+1),children:"Coba lagi"})]}),!J&&pt.length>0&&t.jsxs("div",{className:"hn-terminal-unplaced",children:[t.jsx("span",{className:"hn-terminal-unplaced-label",children:"Belum di grid:"}),pt.map(a=>t.jsxs("span",{className:"hn-terminal-unplaced-chip",children:[t.jsxs("button",{className:"hn-terminal-unplaced-action",disabled:!w,onClick:()=>bn(a.id),title:"Taruh di sel kosong pertama grup ini",children:[a.specId??Q(a.projectId)," · ",a.id.slice(0,6)]}),t.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${a.id}`,onClick:()=>void ht(a.id),children:"×"})]},a.id))]}),!J&&W&&!ot&&t.jsx("div",{className:"hn-stack-mobile hn-terminal-tabs-row",children:t.jsx(Hn,{"aria-label":"Panel terminal",variant:"pill",value:String(ne),onChange:a=>Ue(Number(a)),tabs:z.cells.map((a,i)=>({value:String(i),label:`Panel ${i+1}${a?` · ${a.slice(0,6)}`:" · kosong"}`}))})}),!J&&(ot?Ye?null:t.jsx(Fe,{kind:"empty",icon:"terminal",title:"Belum ada sesi terminal",hint:"Tekan Sesi baru untuk memulai agen di project terpilih, atau Terminal biasa untuk shell."}):t.jsxs("div",{ref:ct,"data-testid":"terminal-grid",className:"hn-terminal-grid",style:{"--grid-cols":W?"minmax(0, 1fr)":`18px ${gt.map(a=>`minmax(0, ${a}fr)`).join(" ")}`,"--grid-rows":W?"minmax(0, 1fr)":`16px ${bt.map(a=>`minmax(0, ${a}fr)`).join(" ")}`},children:[!W&&t.jsx("div",{className:"hn-terminal-grid-corner"}),!W&&Array.from({length:z.cols},(a,i)=>t.jsx(va,{axis:"col",label:`Tutup kolom ${i+1}`,disabled:!w||z.cols===1,gridColumn:i+2,gridRow:1,onClick:()=>void m(c=>X(c,d=>ha(d,i)))},`col-${i}`)),!W&&Array.from({length:z.rows},(a,i)=>t.jsx(va,{axis:"row",label:`Tutup baris ${i+1}`,disabled:!w||z.rows===1,gridColumn:1,gridRow:i+2,onClick:()=>void m(c=>X(c,d=>ma(d,i)))},`row-${i}`)),!W&&Array.from({length:z.cols-1},(a,i)=>{const c=pa(gt,i);return t.jsx(ja,{orientation:"col",label:`Ubah lebar kolom ${i+1}/${i+2}`,now:c.now,min:c.min,max:c.max,disabled:!w,gridColumn:i+3,gridRow:"1 / -1",onPointerDown:d=>Yt("col",i,d),onPointerMove:Jt,onPointerUp:Xt,onKeyDown:d=>Zt("col",i,d),onDoubleClick:()=>Qt("col",i)},`col-div-${i}`)}),!W&&Array.from({length:z.rows-1},(a,i)=>{const c=pa(bt,i);return t.jsx(ja,{orientation:"row",label:`Ubah tinggi baris ${i+1}/${i+2}`,now:c.now,min:c.min,max:c.max,disabled:!w,gridColumn:"1 / -1",gridRow:i+3,onPointerDown:d=>Yt("row",i,d),onPointerMove:Jt,onPointerUp:Xt,onKeyDown:d=>Zt("row",i,d),onDoubleClick:()=>Qt("row",i)},`row-div-${i}`)}),Array.from({length:z.rows},(a,i)=>i).flatMap(a=>Array.from({length:z.cols},(i,c)=>{const d=a*z.cols+c,I=z.cells[d]??null,P=I?ie(I):null;return t.jsx("div",{"data-terminal-cell-index":d,"aria-hidden":W&&ne!==d?"true":"false",className:W&&ne!==d?"hn-terminal-cell-slot is-hidden":"hn-terminal-cell-slot",style:{"--cell-col":W?"auto":c+2,"--cell-row":W?"auto":a+2},children:P?t.jsx(Gi,{session:P,nameOf:Q,...be(P.id),canArrange:w,onReview:g&&Se.onOpenReview,onSessionReview:C&&Se.onOpenSessionReview,titleOf:v&&Se.titleOf,onIntegrate:p&&Se.onIntegrate,onIntegrateSession:S&&Se.onIntegrateSession,specOf:h&&Se.specOf,backlog:s,fontSize:j,showKeys:U,predict:re,diag:Y,screenReader:ue,fullscreen:le===P.id,paneHidden:W&&ne!==d}):t.jsx(Vi,{disabled:!w,unplaced:pt,nameOf:Q,onPick:H=>gn(d,H)})},I??`empty-${d}`)}))]})),J&&t.jsx(qi,{sessionCount:y.length,focused:He,mobile:Z,railItems:Lt.map(a=>({session:a,label:ve(a,Q,v),projectName:Q(a.projectId),status:Oa(a,rt.has(a.id)),startedMs:Ti(a)})),listError:!!Ye,menuFor:fn,onFocus:Te,drawerOpen:Dt,onDrawer:Ft,fullId:le,focusPhases:Xa,paneHandlers:a=>({onExit:be(a).onExit,onPhases:pn(a),onForget:be(a).onForget}),fontSize:j,showKeys:U,onToggleKeys:()=>B(a=>!a),predict:re,diag:Y,screenReader:ue}),Wa&&t.jsx(Bi,{seed:mn,activeIds:Gt,error:Ua,onPick:a=>void Kt(a),onClose:()=>Oe(!1)}),qa&&t.jsx(di,{open:!0,projectId:G,projectName:Q(G),projects:n,onProjectChange:ce,onClose:()=>zt(!1),onCreated:dn}),Ha&&t.jsx(mi,{projectId:G,projects:n,onProjectChange:ce,onClose:()=>nt(!1),onConfirm:a=>void Ot(a)}),Va&&t.jsx(ci,{projects:n,onClose:()=>_e(!1),onRestart:a=>void _t(a)}),lt.dialog,We&&ie(We.sessionId)&&t.jsx(Ui,{kind:We.kind,session:ie(We.sessionId),specOf:h,onIntegrate:p,onIntegrateSession:S,onClose:()=>Pt(null)}),ge&&t.jsx(se,{open:!0,title:"Ganti nama sesi",eyebrow:"terminal",width:420,onClose:()=>{Ge||Ee(null)},footer:t.jsxs(t.Fragment,{children:[t.jsx(_,{size:"sm",variant:"ghost",disabled:Ge,onClick:()=>Ee(null),children:"Batal"}),t.jsx(_,{size:"sm",leftIcon:"save",disabled:Ge,onClick:()=>void Ut(),children:"Simpan"})]}),children:t.jsx(he,{label:"Nama sesi",hint:"Maksimal 80 karakter. Kosongkan untuk kembali ke nama otomatis.",children:t.jsx(It,{"aria-label":"Nama sesi",autoFocus:!0,maxLength:80,value:ge.value,placeholder:ie(ge.id)?ve({...ie(ge.id),name:void 0},Q,v):void 0,onChange:a=>Ee({id:ge.id,value:a.target.value}),onKeyDown:a=>{a.key==="Enter"&&Ut()}})})}),le&&ie(le)&&t.jsx(Hi,{session:ie(le),label:ve(ie(le),Q,v),fontSize:j,showKeys:U,predict:re,diag:Y,screenReader:ue,onClose:()=>at(null)}),Z&&Qa&&t.jsx(se,{open:!0,title:"Tampilan terminal",icon:"sliders",width:420,onClose:()=>Mt(!1),children:ea}),tn,t.jsx(Vn,{toast:un})]})}function ve(e,n,s){if(e.name)return e.name;const r=n(e.projectId),l=e.specId?s==null?void 0:s(e.specId):void 0;return e.specId?`${r} · ${e.specId}${l?` · ${l}`:""}`:e.id.startsWith("xaudit-")?`${r} · audit lintas`:r}function Bi({seed:e,activeIds:n,error:s,onPick:r,onClose:l}){const[u,k]=o.useState(""),[g,C]=o.useState("all"),[v,p]=o.useState("all"),[S,h]=o.useState(e),[x,N]=o.useState(""),[A,E]=o.useState(null);o.useEffect(()=>{const f=setTimeout(()=>N(u.trim()),250);return()=>clearTimeout(f)},[u]),o.useEffect(()=>{var K,V;let f=!0;const D=(V=(K=$).listSpecs)==null?void 0:V.call(K,{startable:!0,q:x||void 0,stage:g==="all"?void 0:g,priority:v==="all"?void 0:v});return D==null||D.then(b=>{f&&(h(b.items),E(null))}).catch(b=>{f&&E(te("memuat backlog",b))}),()=>{f=!1}},[x,g,v]);const T=S.filter(f=>!n.has(f.id)),y=s??A;return t.jsxs(se,{open:!0,title:"Ambil backlog",icon:"inbox",onClose:l,width:760,children:[y&&t.jsx("div",{role:"alert",className:"hn-terminal-pick-notice",children:y}),t.jsxs("div",{className:"hn-terminal-pick-filters",children:[t.jsx(It,{size:"sm",leftIcon:"search",placeholder:"mis. invoice atau SPEC-412","aria-label":"Cari backlog",value:u,onChange:f=>k(f.target.value),className:"hn-terminal-pick-search"}),t.jsx(ee,{size:"sm","aria-label":"Filter stage",value:g,onChange:f=>C(f.target.value),options:[{value:"all",label:"Semua stage"}].concat(ei.filter(f=>f.key!=="done").map(f=>({value:f.key,label:f.label})))}),t.jsx(ee,{size:"sm","aria-label":"Filter prioritas",value:v,onChange:f=>p(f.target.value),options:[{value:"all",label:"Semua prioritas"},{value:"tinggi",label:"Tinggi"},{value:"sedang",label:"Sedang"},{value:"rendah",label:"Rendah"}]})]}),T.length===0?t.jsx(Fe,{kind:"empty",icon:"inbox",title:"Tak ada backlog untuk diambil",hint:"Semua item sudah selesai/aktif atau tak cocok filter — buat brief baru di halaman Backlog."}):t.jsx("div",{className:"hn-terminal-pick-list",children:T.map(f=>t.jsx("button",{onClick:()=>r(f),className:"hn-terminal-pick-row",children:t.jsxs("span",{className:"hn-dense-row hn-picker-row hn-terminal-pick-main",children:[t.jsx(Me,{name:f.source==="qa"?"bug":f.source==="audit"?"search":"lightbulb",size:14,color:f.source==="qa"?"var(--clay-500)":f.source==="audit"?"var(--wind-600)":"var(--brass-500)"}),t.jsx("span",{className:"hn-terminal-pick-id",children:f.id}),t.jsx("span",{className:"hn-picker-title hn-terminal-pick-title",children:f.title}),t.jsx(yt,{tone:f.priority==="tinggi"?"err":"neutral",size:"sm",children:f.priority}),t.jsx("span",{className:"hn-terminal-pick-project",children:f.projectId})]})},f.id))})]})}function Oi({ws:e,compact:n=!1,writable:s,onSelect:r,onAdd:l,onRename:u,onRemove:k}){const[g,C]=o.useState(null),v=Le(e),p=e.groups.length===1,h=Ia()?44:24;return t.jsxs("div",{className:n?"hn-terminal-groups":"hn-terminal-groups is-bordered",style:{"--group-box":`${h}px`},children:[t.jsx("div",{role:"tablist","aria-label":"Grup terminal",className:"hn-terminal-groups-tabs",children:e.groups.map((x,N)=>{const A=x.id===v.id;return t.jsx("button",{type:"button",role:"tab","aria-selected":A,tabIndex:A?0:-1,className:"hn-terminal-group-control hn-terminal-group-tab",onClick:()=>r(x.id),onKeyDown:E=>{var y,f;let T=null;E.key==="ArrowRight"?T=(N+1)%e.groups.length:E.key==="ArrowLeft"?T=(N-1+e.groups.length)%e.groups.length:E.key==="Home"?T=0:E.key==="End"&&(T=e.groups.length-1),T!==null&&(E.preventDefault(),r(e.groups[T].id),(f=(y=E.currentTarget.closest('[role="tablist"]'))==null?void 0:y.querySelectorAll('[role="tab"]')[T])==null||f.focus())},children:x.name},x.id)})}),s&&(g===v.id?t.jsx(Ki,{initial:v.name,onCommit:x=>{x.trim()&&u(v.id,x.trim()),C(null)},onCancel:()=>C(null)},v.id):t.jsxs("span",{role:"group","aria-label":`Kelola grup ${v.name}`,className:"hn-terminal-groups-actions",children:[t.jsx("button",{type:"button",className:"hn-terminal-group-control hn-terminal-group-action","aria-label":`Ganti nama grup ${v.name}`,title:"Ganti nama",onClick:()=>C(v.id),children:"✎"}),t.jsx("button",{type:"button",className:"hn-terminal-group-control hn-terminal-group-action hn-terminal-group-remove","aria-label":`Hapus grup ${v.name}`,title:p?"Grup terakhir tak bisa dihapus":"Hapus grup (sesi tetap hidup)",disabled:p,onClick:()=>k(v.id),children:"×"})]})),t.jsx("button",{type:"button",className:"hn-terminal-group-control hn-terminal-group-action hn-terminal-group-add","aria-label":"Grup baru",title:"Grup baru",disabled:!s,onClick:l,children:"+"})]})}function va({label:e,disabled:n,onClick:s,axis:r,gridColumn:l,gridRow:u}){return t.jsx("button",{type:"button","aria-label":e,title:n?"Grid tak boleh menyusut ke nol":e,disabled:n,onClick:s,className:`hn-terminal-gutter hn-terminal-gutter--${r}`,style:{"--grid-col":l,"--grid-row":u},children:"×"})}function ja({orientation:e,label:n,now:s,min:r,max:l,disabled:u,gridColumn:k,gridRow:g,onPointerDown:C,onPointerMove:v,onPointerUp:p,onKeyDown:S,onDoubleClick:h}){return t.jsx("div",{role:"separator","aria-label":n,"aria-disabled":u,"aria-orientation":e==="col"?"vertical":"horizontal","aria-valuenow":s,"aria-valuemin":r,"aria-valuemax":l,tabIndex:u?-1:0,className:`hn-terminal-divider hn-terminal-divider--${e}`,title:u?void 0:"Seret untuk ubah ukuran — panah untuk langkah kecil, Shift+panah langkah besar, klik dua kali menyamakan",style:{"--grid-col":k,"--grid-row":g},onPointerDown:u?void 0:C,onPointerMove:u?void 0:v,onPointerUp:u?void 0:p,onPointerCancel:u?void 0:p,onKeyDown:u?void 0:S,onDoubleClick:u?void 0:h})}function Ki({initial:e,onCommit:n,onCancel:s}){const[r,l]=o.useState(e);return t.jsx("input",{autoFocus:!0,"aria-label":"Nama grup",value:r,placeholder:"mis. Rilis",onChange:u=>l(u.target.value),onBlur:()=>n(r),onKeyDown:u=>{u.key==="Enter"?n(r):u.key==="Escape"&&s()},className:"hn-terminal-rename"})}const _i={done:"✓",running:"●",pending:"○",skipped:"–",failed:"✕",abandoned:"⨯"};function _a({phases:e,compact:n=!1,now:s,onOpenMockup:r}){const[l,u]=o.useState(null),k=Mn(l!==null,()=>u(null),"dialog"),[,g]=o.useState(0),C=!!(e!=null&&e.some(h=>{var x;return((x=h.agent)==null?void 0:x.status)==="running"}));if(o.useEffect(()=>{if(!(!C||s!==void 0))return ri(()=>g(h=>h+1))},[C,s]),!(e!=null&&e.length))return null;const v=s??Date.now(),p=e.find(h=>h.name===l&&h.agent),S=h=>{const x=h.agent;return x?typeof x.durationMs=="number"?la(x.durationMs):x.status==="running"&&x.startedAt?la(v-Date.parse(x.startedAt)):"":""};return t.jsxs("div",{"data-testid":"phase-strip",className:"hn-terminal-phase",children:[t.jsx("div",{"data-testid":"phase-strip-scroller",className:"hn-terminal-phase-scroller",children:e.map(h=>{const x=!!r&&h.name===sa&&(h.state==="active"||h.state==="done");if(!h.agent)return x?t.jsxs("button",{type:"button","data-state":h.state,onClick:r,"aria-label":"Lihat mockup",title:"Lihat mockup",className:"hn-terminal-phase-chip",children:[t.jsx("span",{"data-state":h.state,className:"hn-terminal-phase-name",children:h.name}),t.jsx("span",{"aria-hidden":!0,children:"· lihat"})]},h.name):t.jsx("span",{"data-state":h.state,title:h.state,className:"hn-terminal-phase-name",children:h.name},h.name);const N=h.agent,A=$n(h),E=!n||h.state==="active",T=S(h);return t.jsxs("button",{type:"button","data-tone":A,"aria-expanded":l===h.name,ref:l===h.name?k.triggerRef:void 0,"aria-haspopup":"dialog","aria-controls":l===h.name?k.panelId:void 0,"aria-label":Pn(h,T),onClick:()=>u(l===h.name?null:h.name),className:"hn-terminal-phase-chip",children:[t.jsx("span",{"aria-hidden":!0,children:_i[A]}),t.jsx("span",{"data-state":h.state,title:h.state,className:"hn-terminal-phase-name",children:h.name}),h.state==="skipped"&&t.jsx("span",{children:"dilewati"}),E&&N.model&&t.jsxs("span",{children:["· ",wt(N.model)]}),E&&N.effort&&t.jsxs("span",{children:["· ",N.effort]}),E&&T&&t.jsxs("span",{children:["· ",T]}),(N.attempts??0)>1&&t.jsxs("span",{children:["↻",N.attempts]}),N.evidence==="missing"&&t.jsx("span",{role:"img","aria-label":"bukti subagent tak diterima",title:"bukti subagent tak diterima",className:"hn-terminal-phase-warn",children:"⚠"})]},h.name)})}),(p==null?void 0:p.agent)&&t.jsxs("div",{ref:k.panelRef,id:k.panelId,role:"dialog","aria-label":`Detail fase ${p.name}`,tabIndex:-1,onKeyDown:k.onKeyDown,className:"hn-terminal-phase-panel",children:[t.jsx("div",{children:t.jsx("b",{children:p.agent.name})}),t.jsx("div",{children:[wt(p.agent.model)||(p.agent.evidence==="unknown"?"model tidak diketahui":""),p.agent.effort??(p.agent.evidence==="unknown"?"effort tidak diketahui":""),p.agent.status??"belum mulai"].filter(Boolean).join(" · ")}),t.jsxs("div",{children:["durasi ",S(p)||(p.agent.evidence==="unknown"?"tidak diketahui":"—")," · percobaan ",p.agent.attempts??"tidak diketahui"]}),t.jsxs("div",{children:["token in ",p.agent.inputTokens??"tidak diketahui"," · out ",p.agent.outputTokens??"tidak diketahui"," · cache ",p.agent.cachedTokens??"tidak diketahui"]}),p.agent.resultExcerpt&&t.jsx("pre",{className:"hn-terminal-phase-excerpt",children:p.agent.resultExcerpt}),r&&p.name===sa&&(p.state==="active"||p.state==="done")&&t.jsx("button",{type:"button",className:"hn-mockup-open",onClick:()=>{u(null),r()},children:"Lihat mockup"})]})]})}const Gi=o.memo(Wi);function Wi({session:e,nameOf:n,onClose:s,onForget:r,canArrange:l,onDetach:u,onExit:k,onReview:g,onSessionReview:C,titleOf:v,onIntegrate:p,onIntegrateSession:S,specOf:h,fontSize:x,showKeys:N,predict:A,diag:E,screenReader:T,fullscreen:y,onFullscreen:f,onDialog:D,onRename:K,paneHidden:V}){const[b,R]=o.useState(null),[F,w]=o.useState(!1),m=o.useRef(null),[M,ae]=o.useState(Number.POSITIVE_INFINITY);o.useEffect(()=>{const Y=m.current;if(!Y||typeof ResizeObserver!="function")return;const ye=new ResizeObserver(ue=>{var Re;const Be=((Re=ue[0])==null?void 0:Re.contentRect.width)??Y.getBoundingClientRect().width;Be>0&&ae(Be)});return ye.observe(Y),()=>ye.disconnect()},[]);const[G,ce]=o.useState(!1),je=o.useCallback((Y,ye)=>{R(Y),ce(ye)},[]),pe=ve(e,n,v),Z=!e.exited&&!!e.decision,j=!e.exited&&!!e.deciding,L=Z||j,U=e.exited&&!!e.exitCode,B=!e.exited&&G,re=U?null:e.exited||B?"PST-005":L?"PST-004":"PST-003",tt=Ga(e,{label:pe,canArrange:l,specOf:h,onReview:g,onSessionReview:C,onIntegrate:p,onIntegrateSession:S,onDialog:D,onDetach:u,onFullscreen:f,onRename:K});return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:e.exited?"hn-terminal-cell-header is-exited":"hn-terminal-cell-header","data-cell-tone":U?"failed":e.exited||B?"done":L?"attention":"idle",children:[re&&t.jsx("span",{className:"hn-terminal-cell-illus",children:t.jsx(ii,{id:re,decorative:!0})}),t.jsxs("span",{className:"hn-terminal-cell-title",children:[pe," · ",e.id.slice(0,6)]}),e.orchestrated&&e.model&&t.jsxs("span",{"data-testid":"orchestrator-chip",title:"Model & effort orchestrator",className:"hn-terminal-orch",children:["orch ",wt(e.model),e.effort?` · ${e.effort}`:""]}),e.exited&&(U?t.jsx(xe,{status:"failed",size:"sm",children:`Gagal · exit ${e.exitCode}`}):t.jsx(xe,{status:"done",size:"sm",children:"Selesai"})),B&&t.jsx(xe,{status:"done",size:"sm",children:"Selesai"}),j&&!B&&t.jsx(xe,{status:"running",size:"sm",children:"Lead memutuskan"}),Z&&!j&&!B&&t.jsx(xe,{status:"awaiting",size:"sm"}),t.jsxs("span",{className:"hn-terminal-actions",children:[t.jsx(Ce,{label:`Aksi sesi ${e.id}`,items:tt}),t.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${e.id}`,title:"Tutup sesi (dikonfirmasi dulu)",onClick:s,children:t.jsx(Me,{name:"x",size:12})})]})]}),t.jsxs("div",{ref:m,className:"hn-terminal-cell-body",children:[e.exited&&t.jsx(Et,{}),t.jsx(_a,{phases:b,compact:M<480,onOpenMockup:e.specId?()=>w(!0):void 0}),F&&e.specId&&t.jsx(Ca,{specId:e.specId,onClose:()=>w(!1)}),t.jsx("div",{className:"hn-terminal-cell-pane",children:y?t.jsx("div",{className:"hn-terminal-cell-fullscreen",children:"Terbuka di layar penuh"}):t.jsx(Ct,{sessionId:e.id,onExit:k,onPhases:je,fontSize:x,showKeys:N,predict:A,diag:E,screenReader:T,hidden:V,onForget:r,label:ve(e,n,v)},e.id)})]})]})}function Ga(e,n){var k;const s=[],r=e.specId?(k=n.specOf)==null?void 0:k.call(n,e.specId):void 0,l=!e.specId&&!!e.branch;e.specId&&s.push({key:"docs",label:"Lihat dokumen",icon:"file-text",title:"Lihat dokumen (audit/spec/plan)",onSelect:()=>n.onDialog("docs")});const u=e.specId;if(u&&n.onReview){const g=n.onReview;s.push({key:"review",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree)",onSelect:()=>g(u)})}if(l&&n.onSessionReview){const g=n.onSessionReview;s.push({key:"review-session",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree sesi)",onSelect:()=>g(e.id,n.label)})}return r&&n.onIntegrate&&s.push({key:"integrate",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch spec",onSelect:()=>n.onDialog("integrate")}),l&&n.onIntegrateSession&&s.push({key:"integrate-session",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch sesi",onSelect:()=>n.onDialog("sessIntegrate")}),n.onRename&&s.push({key:"rename",label:"Ganti nama",icon:"pencil",title:"Beri nama kustom pada sesi ini",onSelect:n.onRename}),s.push({key:"detach",label:"Lepas dari grid",icon:"unlink",disabled:!n.canArrange,title:"Lepas dari grid (sesi tetap hidup)",onSelect:n.onDetach}),s.push({key:"fullscreen",label:"Layar penuh",icon:"fullscreen",title:"Layar penuh — fokus 1 terminal",onSelect:n.onFullscreen}),n.onKill&&s.push({key:"close",label:"Tutup sesi",icon:"square",tone:"danger",title:"Tutup sesi (dikonfirmasi dulu)",onSelect:n.onKill}),s}function Ui({kind:e,session:n,specOf:s,onIntegrate:r,onIntegrateSession:l,onClose:u}){if(e==="docs")return n.specId?t.jsx(ni,{specId:n.specId,onClose:u}):null;if(e==="integrate"){const k=n.specId?s==null?void 0:s(n.specId):void 0;return!k||!r?null:t.jsx(oa,{projectId:k.projectId,ownBranch:`hanoman/${k.id.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,eyebrow:k.id,onClose:u,onIntegrate:(g,C)=>{u(),r(k,g,C)}})}return!n.branch||n.specId||!l?null:t.jsx(oa,{projectId:n.projectId,ownBranch:n.branch,eyebrow:n.id.slice(0,16),onClose:u,onIntegrate:(k,g)=>{u(),l(n,k,g)}})}const ya="Buka sesi lain: ambil backlog, riwayat sesi, atau terminal biasa";function wa({items:e,compact:n=!1}){const[s,r]=o.useState(!1);return t.jsxs(t.Fragment,{children:[n?t.jsxs("button",{type:"button",className:"hn-terminal-open-compact","aria-label":"Buka…",title:ya,"aria-haspopup":"dialog","aria-expanded":s,onClick:()=>r(!0),children:[t.jsx(Me,{name:"folder-open",size:16}),t.jsx("span",{className:"hn-terminal-open-text",children:"Buka…"})]}):t.jsx(_,{size:"sm",variant:"ghost","aria-haspopup":"dialog","aria-expanded":s,title:ya,onClick:()=>r(!0),children:"Buka…"}),s&&t.jsx(se,{open:!0,title:"Buka sesi",icon:"terminal",width:420,onClose:()=>r(!1),children:t.jsx("div",{className:"hn-terminal-menu-list",children:e.map(l=>t.jsxs("button",{type:"button",disabled:l.disabled,title:l.title,className:"hn-overflow-item",onClick:()=>{r(!1),l.onSelect()},children:[l.icon&&t.jsx(Me,{name:l.icon,size:15}),l.label]},l.key))})})]})}function qi({sessionCount:e,focused:n,railItems:s,mobile:r,listError:l,menuFor:u,onFocus:k,drawerOpen:g,onDrawer:C,fullId:v,focusPhases:p,paneHandlers:S,fontSize:h,showKeys:x,onToggleKeys:N,predict:A,diag:E,screenReader:T}){const y=n?s.find(K=>K.session.id===n.id):void 0,[f,D]=o.useState(null);return t.jsxs("div",{className:"hn-terminal-focus","data-testid":"terminal-focus",children:[!r&&e>0&&t.jsxs("aside",{className:"hn-terminal-rail","aria-label":"Sesi terminal",children:[t.jsxs("div",{className:"hn-terminal-rail-head",children:[t.jsx("span",{children:"Sesi"}),t.jsx("span",{children:e})]}),t.jsx("div",{className:"hn-terminal-rail-scroll",children:t.jsx(xa,{items:s,focusedId:(n==null?void 0:n.id)??null,onFocus:k,menuFor:u})})]}),t.jsx("section",{className:"hn-terminal-focus-main","aria-label":"Terminal fokus",children:n&&y?t.jsxs(t.Fragment,{children:[t.jsxs("header",{className:"hn-terminal-focus-head",children:[t.jsxs("span",{className:"hn-terminal-focus-title",title:y.label,children:[y.label," · ",n.id.slice(0,6)]}),t.jsx(xe,{status:Ka[y.status.tone],size:"sm",variant:"dot",children:y.status.label}),t.jsx(Ce,{label:`Aksi sesi ${n.id}`,items:u(n)})]}),n.exited&&t.jsx(Et,{}),t.jsx(_a,{compact:r,phases:(p==null?void 0:p.sessionId)===n.id?p.phases:null,onOpenMockup:n.specId?()=>D(n.specId):void 0}),f&&t.jsx(Ca,{specId:f,onClose:()=>D(null)}),t.jsx("div",{className:"hn-terminal-focus-body",children:v===n.id?t.jsx("div",{className:"hn-terminal-focus-placeholder",children:"Terbuka di layar penuh"}):t.jsx(Ct,{sessionId:n.id,...S(n.id),fontSize:h,showKeys:x,predict:A,diag:E,screenReader:T,composer:!0,compact:r,onToggleKeys:N,label:y.label},n.id)})]}):l?null:t.jsx(Fe,{kind:"empty",icon:"terminal",title:"Belum ada sesi terminal",hint:"Tekan Sesi baru untuk memulai agen di project terpilih, atau Terminal biasa untuk shell."})}),r&&g&&t.jsx(se,{open:!0,title:"Sesi terminal",icon:"terminal",width:460,onClose:()=>C(!1),children:t.jsx(xa,{items:s,focusedId:(n==null?void 0:n.id)??null,onFocus:K=>{k(K),C(!1)},menuFor:u})})]})}function Et(){return t.jsxs("div",{role:"status","data-testid":"terminal-ended",className:"hn-terminal-ended",children:[t.jsx("strong",{className:"hn-terminal-ended-title",children:"Berakhir"}),t.jsx("span",{className:"hn-terminal-ended-body",children:"Agen sudah berhenti. Output tetap bisa dibaca; tutup sel bila tak diperlukan lagi."})]})}function Hi({session:e,label:n,fontSize:s,showKeys:r,predict:l,diag:u,screenReader:k,onClose:g}){return t.jsx(se,{open:!0,icon:"terminal",title:n,onClose:g,closeOnEscape:!1,width:1600,children:t.jsxs("div",{className:"hn-terminal-fullscreen-body",children:[e.exited&&t.jsx(Et,{}),t.jsx(Ct,{sessionId:e.id,onExit:()=>{},fontSize:s,showKeys:r,predict:l,diag:u,screenReader:k},e.id)]})})}function Vi({unplaced:e,nameOf:n,onPick:s,disabled:r}){return t.jsx("div",{className:"hn-terminal-empty-cell",children:t.jsx(ee,{size:"sm",value:"","aria-label":"Pilih sesi untuk sel",disabled:r||!e.length,onChange:l=>l.target.value&&s(l.target.value),options:[{value:"",label:e.length?"Pilih sesi…":"tidak ada sesi bebas"}].concat(e.map(l=>({value:l.id,label:`${l.specId??n(l.projectId)} · ${l.id.slice(0,6)}`})))})})}export{_a as PhaseStrip,es as TerminalScreen,Ga as sessionMenuItems};