hanoman 0.9.19 → 0.9.21

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 (64) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/cli.js +2966 -775
  3. package/dist/server.js +10106 -8155
  4. package/docs/agent-integration.md +208 -97
  5. package/package.json +1 -1
  6. package/prisma/migrations/20261010070000_remove_memory_changelog/migration.sql +40 -0
  7. package/prisma/migrations/20261012100000_spec_reviewed_at/migration.sql +13 -0
  8. package/prisma/schema.prisma +7 -80
  9. package/web/assets/DalangHanomanScreen-Us_5qG25.js +13 -0
  10. package/web/assets/DalangHanomanScreen-gk7fa9dl.css +1 -0
  11. package/web/assets/{DocPreviewModal-CHrsP0pL.js → DocPreviewModal-CJP6d0Hx.js} +1 -1
  12. package/web/assets/DocsWorkspace-CSak7xFX.css +1 -0
  13. package/web/assets/DocsWorkspace-zGpPd7u3.js +3 -0
  14. package/web/assets/IdeScreen-CppUucs0.css +10 -0
  15. package/web/assets/IdeScreen-DTvfuR2n.js +2 -0
  16. package/web/assets/LeadScreen-CN53yR_e.css +1 -0
  17. package/web/assets/LeadScreen-DWbunLkQ.js +1 -0
  18. package/web/assets/ReviewScreen-Ch9UiKlx.js +1 -0
  19. package/web/assets/SchedulerScreen-zIUh-Vbe.js +1 -0
  20. package/web/assets/SettingsScreen-CLMuCJ6R.js +62 -0
  21. package/web/assets/SettingsScreen-DQZ3K43g.css +1 -0
  22. package/web/assets/TeamScreen-CV1R5Ekk.js +1 -0
  23. package/web/assets/TeamScreen-CtkpFpCF.css +1 -0
  24. package/web/assets/TerminalScreen-DrgZKlw2.css +1 -0
  25. package/web/assets/TerminalScreen-QVjhjrxx.js +2 -0
  26. package/web/assets/TriageScreen-B6_KrS6l.css +1 -0
  27. package/web/assets/TriageScreen-Dpj4YrBQ.js +1 -0
  28. package/web/assets/VpsScreen-BzXpc3le.css +1 -0
  29. package/web/assets/VpsScreen-DX_HEquM.js +2 -0
  30. package/web/assets/index-CL0_zz87.css +32 -0
  31. package/web/assets/index-DmnwLncG.js +1012 -0
  32. package/web/assets/live-B193WtZm.js +1 -0
  33. package/web/assets/sched-lead-shared-BjMO8Q_k.js +1 -0
  34. package/web/assets/scheduler-CQt-VP9-.css +1 -0
  35. package/web/assets/settings-rebase-BI7-Bk98.js +1 -0
  36. package/web/index.html +10 -3
  37. package/web/assets/ChangelogScreen-DL5v_FZf.js +0 -1
  38. package/web/assets/DalangHanomanScreen-aLBtUGE4.js +0 -1
  39. package/web/assets/DocsWorkspace-D262CVxH.js +0 -3
  40. package/web/assets/IdeScreen-BfC0goYb.css +0 -10
  41. package/web/assets/IdeScreen-D2GI3KYh.js +0 -2
  42. package/web/assets/LeadScreen-eb_DK1j6.js +0 -1
  43. package/web/assets/ReviewScreen-DarOFH_a.js +0 -1
  44. package/web/assets/SchedulerScreen-DKoMf2LT.js +0 -1
  45. package/web/assets/SettingsScreen-BAUhwd5K.js +0 -62
  46. package/web/assets/TeamScreen-C2fSsQ8C.js +0 -1
  47. package/web/assets/TerminalScreen-GsfOMtu5.js +0 -2
  48. package/web/assets/TriageScreen-DdKMAroz.js +0 -1
  49. package/web/assets/VpsScreen-CDAjvyT1.js +0 -2
  50. package/web/assets/hnm-blencong-v01-CBBfchr0.webp +0 -0
  51. package/web/assets/hnm-dalang-six-arms-v01-DeBacuq8.webp +0 -0
  52. package/web/assets/hnm-hero-rig-arm-ml-v01-Kts3pjTf.webp +0 -0
  53. package/web/assets/hnm-hero-rig-arm-mr-v01-DQgnE6bD.webp +0 -0
  54. package/web/assets/hnm-hero-rig-arm-ul-v01-CIAWAxFe.webp +0 -0
  55. package/web/assets/hnm-hero-rig-arm-ur-v01-C0R0CZnp.webp +0 -0
  56. package/web/assets/hnm-hero-rig-body-v01-DmbKJJHB.webp +0 -0
  57. package/web/assets/hnm-wayang-panakawan-v01-1LGv-V8N.webp +0 -0
  58. package/web/assets/hnm-wayang-project-v01-BG9EZqzn.webp +0 -0
  59. package/web/assets/hnm-wayang-putri-v01-F6p69kHq.webp +0 -0
  60. package/web/assets/hnm-wayang-satria-alus-v01-CpfoXKTy.webp +0 -0
  61. package/web/assets/hnm-wayang-satria-gagah-v01-bLfIYAsv.webp +0 -0
  62. package/web/assets/index-DI8I0VA5.css +0 -32
  63. package/web/assets/index-gNO91_qw.js +0 -1063
  64. package/web/assets/live-Cz6dWAau.js +0 -1
@@ -1 +0,0 @@
1
- import{T as Ae,j as t,F as G,L as lt,B as ae,I as X,a as B,S as M,u as Ue,M as xe,c as $,d as O,H as ot,e as w,P as Te,E as dt,s as ct,f as H,g as de,h as A,o as we,k as ut,l as mt,m as pt,R as gt,n as ht,p as ce,q as ft}from"./index-gNO91_qw.js";import{R as m}from"./react-DfGhg7ZW.js";import{L as xt}from"./live-Cz6dWAau.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";const bt={backlog:"Backlog",doing:"Dikerjakan",review:"Review",done:"Selesai"},K=Ae.map(e=>({key:e,label:bt[e]})),vt=()=>Object.fromEntries(Ae.map(e=>[e,[]])),pe=(e,a)=>e!==a,He=e=>e.length===0?0:e.reduce((a,n)=>n.order>a?n.order:a,-1/0)+1;function yt(e,a,n,r){if(!pe(n,r))return null;const l=e[n].find(g=>g.id===a);if(!l)return null;const o={status:r,order:He(e[r])},d={...e};return d[n]=e[n].filter(g=>g.id!==a),d[r]=[...e[r],{...l,...o}],{board:d,patch:o}}function ue(e,a){const n={...e};return n[a.status]=e[a.status].map(r=>r.id===a.id?a:r),n}const De=e=>e?e.slice(0,10):"",Ee=e=>/^\d{4}-\d{2}-\d{2}$/.test(e)?`${e}T12:00:00.000Z`:null,F=864e5,ee=e=>Math.floor(e/F)*F,Me=e=>{if(!e)return null;const a=new Date(e).getTime();return Number.isFinite(a)?a:null};function Y(e){const a=Me(e.startDate),n=Me(e.dueDate);if(a===null&&n===null)return null;const r=a??n,l=n??a;return{start:ee(Math.min(r,l)),end:ee(Math.max(r,l))+F,invalid:l<r}}const jt=new Intl.DateTimeFormat("id-ID",{day:"numeric",month:"short",timeZone:"UTC"}),Be=e=>e?jt.format(new Date(e)):null;function Q(e){const a=Be(e.startDate),n=Be(e.dueDate);return a&&n?`${a} → ${n}`:n?`→ ${n}`:a}const Le=["day","week","month"],Ke={day:{cell:34,minTicks:14},week:{cell:56,minTicks:8},month:{cell:84,minTicks:6}},kt=e=>Ke[e].cell,St=120,It=(e,a)=>{const n=ee(e);if(a==="day")return n;if(a==="week")return n-(new Date(n).getUTCDay()+6)%7*F;const r=new Date(n);return Date.UTC(r.getUTCFullYear(),r.getUTCMonth(),1)},Ct=(e,a)=>{if(a==="day")return e+F;if(a==="week")return e+7*F;const n=new Date(e);return Date.UTC(n.getUTCFullYear(),n.getUTCMonth()+1,1)},Tt=new Intl.DateTimeFormat("id-ID",{day:"numeric",timeZone:"UTC"}),$e=new Intl.DateTimeFormat("id-ID",{day:"numeric",month:"short",timeZone:"UTC"}),wt=new Intl.DateTimeFormat("id-ID",{month:"short",timeZone:"UTC"}),Dt=new Intl.DateTimeFormat("id-ID",{month:"short",year:"2-digit",timeZone:"UTC"}),Et=(e,a)=>{const n=new Date(e);return a==="day"?n.getUTCDate()===1:a==="week"?n.getUTCDate()<=7:n.getUTCMonth()===0},Mt=(e,a,n)=>{const r=new Date(e);return a==="day"?(n?$e:Tt).format(r):a==="week"?$e.format(r):(n?Dt:wt).format(r)};function Ge(e,a,n){const r=ee(n);let l=r,o=r+F;for(const c of e)c.start<l&&(l=c.start),c.end>o&&(o=c.end);const d=It(l,a),{minTicks:g}=Ke[a],u=[];let i=d;for(;u.length<St&&(i<o||u.length<g);){const c=Et(i,a);u.push({start:i,label:Mt(i,a,c),major:c}),i=Ct(i,a)}return{from:d,to:i,zoom:a,ticks:u}}function Ye(e,a){const n=a.to-a.from;if(n<=0||e.end<=a.from||e.start>=a.to)return null;const r=Math.max(e.start,a.from),l=Math.min(e.end,a.to);return{left:(r-a.from)/n*100,width:(l-r)/n*100,clippedStart:e.start<a.from,clippedEnd:e.end>a.to,invalid:e.invalid}}function ge(e,a){const n=Y(e);return n?Ye(n,a):null}function Bt(e){let a=1/0,n=-1/0,r=!1;for(const l of e){const o=Y(l);o&&(o.start<a&&(a=o.start),o.end>n&&(n=o.end),o.invalid&&(r=!0))}return a===1/0?null:{start:a,end:n,invalid:r}}function Lt(e,a){const n=ee(a);return n<e.from||n>=e.to?null:(n-e.from)/(e.to-e.from)*100}function $t(e,a){const n=[],r=[],l=[];for(const o of e){const d=Y(o);if(!d){r.push(o);continue}const g=ge(o,a);if(!g){l.push(o);continue}n.push({task:o,geometry:g,start:d.start})}return n.sort((o,d)=>o.start-d.start||o.task.title.localeCompare(d.task.title,"id")||o.task.id.localeCompare(d.task.id)),{rows:n.map(({task:o,geometry:d})=>({task:o,geometry:d})),unscheduled:r,outside:l}}const ze=(e,a)=>e.title.localeCompare(a.title,"id")||e.id.localeCompare(a.id);function zt(e,a,n){const r=Symbol("no-project"),l=new Map;for(const u of e){const i=u.projectId??r,c=l.get(i);c?c.tasks.push(u):l.set(i,{projectId:u.projectId,tasks:[u]})}const o=[...l.values()].map(({projectId:u,tasks:i})=>{const c=Bt(i),p=[],v=[];for(const x of i){const h=Y(x);h?p.push({task:x,start:h.start}):v.push(x)}return p.sort((x,h)=>x.start-h.start||ze(x.task,h.task)),v.sort(ze),{projectId:u,span:c,geometry:c?Ye(c,a):null,tasks:[...p.map(x=>x.task),...v]}}),d=u=>u.geometry?0:u.span?1:2,g=u=>u.projectId===null?[1,""]:[0,u.projectId];return o.sort((u,i)=>{const[c,p]=g(u),[v,x]=g(i);return d(u)-d(i)||(u.span&&i.span?u.span.start-i.span.start:0)||n(u.projectId).localeCompare(n(i.projectId),"id")||c-v||p.localeCompare(x)}),o}const Ot={tinggi:"err",sedang:"neutral",rendah:"neutral"};function Rt({task:e,members:a,dragging:n,onDragStart:r,onDragEnd:l,onOpen:o,onMove:d,onAssign:g,onEscalate:u,onUnlink:i}){var v;const c=((v=a.find(x=>x.id===e.memberId))==null?void 0:v.name)??"belum ditugaskan",p=Q(e);return t.jsxs("div",{draggable:!0,"data-testid":`team-card-${e.id}`,onDragStart:x=>{x.dataTransfer.effectAllowed="move",x.dataTransfer.setData("text/plain",e.id),r()},onDragEnd:l,style:{flex:"0 0 auto",background:"var(--surface-card)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",padding:10,boxShadow:"var(--shadow-xs)",cursor:"grab",opacity:n?.4:1},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:6},children:[t.jsx(ae,{tone:Ot[e.priority]??"neutral",size:"sm",variant:e.priority==="tinggi"?"soft":"outline",children:e.priority}),t.jsx("span",{style:{flex:1}}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.projectId??"tanpa project"})]}),t.jsx("button",{type:"button",onClick:()=>o(e),style:{display:"block",width:"100%",textAlign:"left",border:"none",background:"none",padding:0,cursor:"pointer",fontFamily:"var(--font-ui)",fontSize:13,fontWeight:"var(--weight-medium)",color:"var(--text-strong)",lineHeight:1.35},children:e.title}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginTop:6,flexWrap:"wrap",fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:[t.jsx(X,{name:"user",size:12,color:"var(--text-subtle)"}),t.jsx("span",{children:c}),p&&t.jsxs(t.Fragment,{children:[t.jsx("span",{"aria-hidden":"true",children:"·"}),t.jsx("span",{children:p})]})]}),t.jsx("div",{style:{display:"flex",alignItems:"center",gap:6,marginTop:6,flexWrap:"wrap"},children:e.specId?t.jsxs(t.Fragment,{children:[t.jsx(ae,{tone:e.spec?"ok":"warn",size:"sm",icon:e.spec?"link":"unlink",children:e.spec?`${e.spec.id} · ${e.spec.stage}`:"tautan putus"}),t.jsx(B,{size:"sm",variant:"ghost",leftIcon:"unlink","aria-label":`Lepas tautan: ${e.title}`,onClick:()=>i(e),children:"Lepas tautan"})]}):t.jsx(B,{size:"sm",variant:"ghost",leftIcon:"git-branch","aria-label":`Eskalasi ke backlog: ${e.title}`,onClick:()=>u(e),children:"Eskalasi"})}),t.jsxs("div",{style:{display:"flex",gap:6,marginTop:8},children:[t.jsx(M,{size:"sm",value:e.status,"aria-label":`Pindah kolom: ${e.title}`,onChange:x=>d(e,x.target.value),options:K.map(x=>({value:x.key,label:x.label})),style:{flex:1,minWidth:0}}),t.jsx(M,{size:"sm",value:e.memberId??"","aria-label":`Tugaskan: ${e.title}`,onChange:x=>g(e,x.target.value||null),options:[{value:"",label:"Belum ditugaskan"},...a.map(x=>({value:x.id,label:x.name}))],style:{flex:1,minWidth:0}})]})]})}function Pt({board:e,totals:a,columns:n,members:r,onMove:l,onAssign:o,onOpen:d,onEscalate:g,onUnlink:u}){const[i,c]=m.useState(null),[p,v]=m.useState(null),x=h=>{i&&pe(i.from,h)&&l(i.task,h),c(null),v(null)};return t.jsx("div",{"data-testid":"team-board",className:"hn-board-local-overflow",style:{flex:"1 1 auto",minHeight:0,display:"flex",gap:10,overflowX:"auto",overflowY:"hidden",alignItems:"stretch",paddingBottom:4},children:n.map(h=>{const y=e[h.key],f=!!i&&pe(i.from,h.key),k=f&&p===h.key,L=Math.max(0,(a[h.key]??0)-y.length);return t.jsxs("div",{"data-testid":`team-col-${h.key}`,onDragOver:S=>{f&&(S.preventDefault(),S.dataTransfer.dropEffect="move",v(h.key))},onDragLeave:()=>v(S=>S===h.key?null:S),onDrop:S=>{S.preventDefault(),x(h.key)},style:{flex:"0 0 244px",display:"flex",flexDirection:"column",minHeight:0,padding:10,borderRadius:"var(--radius-lg)",background:k?"var(--brass-100)":"var(--bone-100)",border:`1px ${f?"dashed":"solid"} ${k?"var(--brass-500)":"var(--border-hair)"}`,opacity:i&&!f?.5:1,transition:"var(--transition-fast)"},children:[t.jsxs("div",{style:{...G,display:"flex",alignItems:"center",gap:6,marginBottom:8},children:[t.jsx("span",{className:"hn-eyebrow",children:h.label}),t.jsx("span",{style:{flex:1}}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)"},children:y.length})]}),t.jsx("div",{style:{...lt,display:"flex",flexDirection:"column",gap:8},children:y.map(S=>t.jsx(Rt,{task:S,members:r,dragging:(i==null?void 0:i.task.id)===S.id,onDragStart:()=>c({task:S,from:h.key}),onDragEnd:()=>{c(null),v(null)},onOpen:d,onMove:l,onAssign:o,onEscalate:g,onUnlink:u},S.id))}),L>0&&t.jsxs("div",{style:{...G,marginTop:8,fontSize:"var(--text-xs)",color:"var(--amber-600)"},children:["menampilkan ",y.length," dari ",a[h.key]," — persempit penyaring"]})]},h.key)})})}const U=232,he=34,me=6,_t={brass:{bg:"var(--brass-300)",border:"var(--brass-500)"},err:{bg:"var(--status-err-tint)",border:"var(--status-err)"},muted:{bg:"var(--bone-300)",border:"var(--border-strong)"},envelope:{bg:"var(--bone-200)",border:"var(--border-hair)"}},Oe={position:"sticky",left:0,zIndex:1,flex:`0 0 ${U}px`,width:U,boxSizing:"border-box",padding:"5px 10px",minWidth:0,background:"var(--surface-card)",borderRight:"1px solid var(--border-hair)"},V={overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"};function Nt({spec:e}){const a=e.geometry,n=_t[e.tone];return t.jsxs("button",{type:"button","data-testid":`timeline-bar-${e.key}`,"data-tone":e.tone,"data-invalid":a.invalid?"true":"false","data-clipped-start":a.clippedStart?"true":"false","data-clipped-end":a.clippedEnd?"true":"false",title:e.title,"aria-label":e.title,onClick:e.onClick,style:{position:"absolute",top:me,height:he-me*2,left:`${a.left}%`,width:`${a.width}%`,minWidth:3,minHeight:he-me*2,display:"flex",alignItems:"center",padding:0,overflow:"hidden",background:n.bg,border:`1px solid ${n.border}`,borderTopLeftRadius:a.clippedStart?0:"var(--radius-sm)",borderBottomLeftRadius:a.clippedStart?0:"var(--radius-sm)",borderTopRightRadius:a.clippedEnd?0:"var(--radius-sm)",borderBottomRightRadius:a.clippedEnd?0:"var(--radius-sm)",cursor:e.onClick?"pointer":"default"},children:[a.clippedStart&&t.jsx(X,{name:"chevron-left",size:11,color:n.border}),t.jsx("span",{style:{flex:1}}),a.clippedEnd&&t.jsx(X,{name:"chevron-right",size:11,color:n.border})]})}function Ze({window:e,rows:a,today:n,emptyHint:r,testId:l,labelHead:o}){const d=kt(e.zoom),g=e.ticks.length*d,u=Lt(e,n),i={position:"relative",width:g,height:he,flex:`0 0 ${g}px`,backgroundImage:`repeating-linear-gradient(to right, var(--border-hair) 0 1px, transparent 1px ${d}px)`};return t.jsx("div",{"data-testid":l??"team-timeline",className:"hn-timeline-scroll",style:{flex:"1 1 auto",minHeight:0,minWidth:0,maxWidth:"100%",overflowX:"auto",overflowY:"auto"},children:t.jsxs("div",{"data-testid":"timeline-canvas",style:{position:"relative",minWidth:U+g,width:U+g},children:[t.jsxs("div",{style:{display:"flex",position:"sticky",top:0,zIndex:2,background:"var(--bone-100)",borderBottom:"1px solid var(--border-hair)"},children:[t.jsx("div",{style:{...Oe,zIndex:3,background:"var(--bone-100)"},children:t.jsx("span",{className:"hn-eyebrow",children:o??"Tugas"})}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:`repeat(${e.ticks.length}, ${d}px)`,width:g,flex:`0 0 ${g}px`},children:e.ticks.map(c=>t.jsx("div",{"data-testid":"timeline-tick",style:{borderLeft:`1px solid ${c.major?"var(--border-strong)":"var(--border-hair)"}`,padding:"5px 4px",fontFamily:"var(--font-mono)",fontSize:10,...V,color:c.major?"var(--text-body)":"var(--text-subtle)"},children:c.label},c.start))})]}),a.length===0?t.jsx("div",{"data-testid":"timeline-empty",style:{position:"sticky",left:0,width:U,padding:"18px 10px",fontSize:"var(--text-xs)",color:"var(--text-muted)"},children:r??"Tak ada yang bisa dihamparkan di jendela ini."}):a.map(c=>t.jsxs("div",{"data-testid":`timeline-row-${c.key}`,style:{display:"flex",borderBottom:"1px solid var(--border-hair)"},children:[t.jsxs("div",{style:Oe,children:[t.jsx("div",{style:{...V,fontSize:12,fontWeight:"var(--weight-medium)",color:"var(--text-strong)"},children:c.label}),c.meta&&t.jsx("div",{style:{...V,fontSize:10,color:"var(--text-subtle)"},children:c.meta})]}),t.jsx("div",{style:i,children:c.bars.map(p=>t.jsx(Nt,{spec:p},p.key))})]},c.key)),u!==null&&t.jsx("div",{"data-testid":"timeline-today","aria-hidden":"true",style:{position:"absolute",top:0,bottom:0,width:2,pointerEvents:"none",left:U+u/100*g,background:"var(--brass-500)",opacity:.5}})]})})}function Re({testId:e,icon:a,title:n,hint:r,tasks:l,onOpen:o}){return l.length===0?null:t.jsxs("div",{"data-testid":e,style:{...G,marginTop:10,padding:10,background:"var(--bone-100)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:6,flexWrap:"wrap"},children:[t.jsx(X,{name:a,size:13,color:"var(--text-subtle)"}),t.jsxs("span",{className:"hn-eyebrow",children:[n," · ",l.length]}),r&&t.jsx("span",{style:{fontSize:"var(--text-xs)",color:"var(--text-muted)"},children:r})]}),t.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:6},children:l.map(d=>t.jsx("button",{type:"button",onClick:()=>o(d),style:{padding:"3px 10px",background:"var(--surface-card)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-pill)",fontFamily:"var(--font-ui)",fontSize:12,color:"var(--text-body)",cursor:"pointer"},children:d.title},d.id))})]})}function Ft({tasks:e,members:a,zoom:n,today:r,hidden:l,onOpen:o}){const d=m.useMemo(()=>{const p=e.map(Y).filter(v=>v!==null);return Ge(p,n,r)},[e,n,r]),{rows:g,unscheduled:u,outside:i}=m.useMemo(()=>$t(e,d),[e,d]),c=m.useMemo(()=>g.map(({task:p,geometry:v})=>{var f;const x=((f=a.find(k=>k.id===p.memberId))==null?void 0:f.name)??"belum ditugaskan",h=Q(p),y=[v.invalid?"tenggat mendahului mulai":null,v.clippedStart||v.clippedEnd?"melewati tepi jendela":null].filter(Boolean);return{key:p.id,label:p.title,meta:h?`${x} · ${h}`:x,bars:[{key:p.id,geometry:v,tone:v.invalid?"err":p.status==="done"?"muted":"brass",title:[p.title,h,...y].filter(Boolean).join(" · "),onClick:()=>o(p)}]}}),[g,a,o]);return t.jsxs(t.Fragment,{children:[t.jsx(Ze,{window:d,rows:c,today:r,emptyHint:"Belum ada tugas bertanggal — isi mulai atau tenggat di kartunya."}),l>0&&t.jsxs("div",{"data-testid":"timeline-truncated",style:{...G,marginTop:8,fontSize:"var(--text-xs)",color:"var(--amber-600)"},children:[l," tugas tak termuat karena plafon 200 per kolom — persempit penyaring"]}),t.jsx(Re,{testId:"timeline-unscheduled",icon:"calendar-off",title:"Belum dijadwalkan",tasks:u,onOpen:o}),t.jsx(Re,{testId:"timeline-outside",icon:"chevrons-left-right",title:"Di luar jendela",hint:"pilih zoom yang lebih lebar",tasks:i,onOpen:o})]})}const Wt="__none__",At=16,Pe=(e,a)=>a.invalid?"err":e.status==="done"?"muted":"brass",_e=(e,a,n)=>[e.title,n,a.invalid?"tenggat mendahului mulai":null,a.clippedStart||a.clippedEnd?"melewati tepi jendela":null].filter(Boolean).join(" · ");function Ut({testId:e,open:a,name:n,count:r,onClick:l}){return t.jsxs("button",{type:"button",onClick:l,"data-testid":e,"aria-expanded":a,style:{display:"flex",alignItems:"center",gap:5,width:"100%",padding:0,background:"none",border:"none",cursor:"pointer",textAlign:"left",minHeight:0,fontFamily:"var(--font-ui)",fontSize:12,fontWeight:"var(--weight-medium)",color:"var(--text-strong)"},children:[t.jsx(X,{name:a?"chevron-down":"chevron-right",size:12,color:"var(--text-subtle)"}),t.jsx("span",{style:{...V,flex:1},children:n}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:10,color:"var(--text-subtle)"},children:r})]})}function Ht({tasks:e,projects:a,members:n,zoom:r,today:l,hidden:o,expanded:d,onToggle:g,onOpen:u}){const i=m.useMemo(()=>{const h=e.map(Y).filter(y=>y!==null);return Ge(h,r,l)},[e,r,l]),c=m.useCallback(h=>{var y;return h===null?"Tanpa project":((y=a.find(f=>f.id===h))==null?void 0:y.name)??h},[a]),p=m.useMemo(()=>zt(e,i,c),[e,i,c]),v=m.useMemo(()=>new Set(d),[d]),x=m.useMemo(()=>{var y;const h=[];for(const f of p){const k=f.projectId??Wt,L=v.has(k),S=c(f.projectId),b=f.geometry?Q({startDate:new Date(f.span.start).toISOString(),dueDate:new Date(f.span.end-1).toISOString()}):f.span?"di luar jendela · pilih zoom yang lebih lebar":"belum dijadwalkan",D=[];if(f.geometry){D.push({key:`span:${k}`,geometry:f.geometry,tone:f.geometry.invalid?"err":"envelope",title:`${S} · ${b??""}`.trim(),onClick:()=>g(k)});for(const C of f.tasks){const E=ge(C,i);E&&D.push({key:`seg:${C.id}`,geometry:E,tone:Pe(C,E),title:_e(C,E,Q(C)),onClick:()=>u(C)})}}if(h.push({key:`p:${k}`,meta:b,bars:D,label:t.jsx(Ut,{testId:`expand-${k}`,open:L,name:S,count:f.tasks.length,onClick:()=>g(k)})}),!!L)for(const C of f.tasks){const E=ge(C,i),j=((y=n.find(_=>_.id===C.memberId))==null?void 0:y.name)??"belum ditugaskan",P=Q(C);h.push({key:`t:${C.id}`,label:t.jsx("span",{style:{...V,display:"block",paddingLeft:At},children:C.title}),meta:P?`${j} · ${P}`:j,bars:E?[{key:`t:${C.id}`,geometry:E,tone:Pe(C,E),title:_e(C,E,P),onClick:()=>u(C)}]:[]})}}return h},[p,v,c,i,n,g,u]);return t.jsxs(t.Fragment,{children:[t.jsx(Ze,{window:i,rows:x,today:l,testId:"team-projects",labelHead:"Project",emptyHint:"Belum ada project bertanggal — isi mulai atau tenggat di kartunya."}),o>0&&t.jsxs("div",{"data-testid":"projects-truncated",style:{...G,marginTop:8,fontSize:"var(--text-xs)",color:"var(--amber-600)"},children:[o," tugas tak termuat karena plafon 200 per kolom — amplop project bisa lebih pendek dari rentang sebenarnya; persempit kolom, anggota, atau pencarian"]})]})}const fe={tinggi:"Tinggi",sedang:"Sedang",rendah:"Rendah"},Kt=Object.keys(fe).map(e=>({value:e,label:fe[e]})),Ne=(e,a)=>({title:(e==null?void 0:e.title)??"",detail:(e==null?void 0:e.detail)??"",projectId:e?e.projectId??"":a??"",status:(e==null?void 0:e.status)??"backlog",priority:e&&e.priority in fe?e.priority:"sedang",memberId:(e==null?void 0:e.memberId)??"",startDate:De((e==null?void 0:e.startDate)??null),dueDate:De((e==null?void 0:e.dueDate)??null)});function Gt({open:e,task:a,projects:n,members:r,defaultProjectId:l,orderFor:o,onClose:d,onSaved:g,onToast:u}){const[i,c]=m.useState(()=>Ne(a,l)),[p,v]=m.useState(!1),{confirm:x,dialog:h}=Ue(),y=`${e?"1":"0"}:${(a==null?void 0:a.id)??""}`,f=m.useRef(y);if(f.current!==y&&(f.current=y,e&&c(Ne(a,l))),!e)return null;const k=b=>c(D=>({...D,...b}));async function L(){if(!i.title.trim()){u("Judul tugas wajib diisi","err","x-circle");return}v(!0);const b=!a||a.status!==i.status,D={title:i.title.trim(),detail:i.detail.trim()||null,projectId:i.projectId||null,status:i.status,priority:i.priority,memberId:i.memberId||null,startDate:Ee(i.startDate),dueDate:Ee(i.dueDate),...b?{order:o(i.status)}:{}};try{a?await w.patchTask(a.id,D):await w.createTask(D),u(a?"Tugas diperbarui":"Tugas dibuat","ok","check"),g(),d()}catch{u("Gagal menyimpan tugas","err","x-circle")}finally{v(!1)}}async function S(){a&&await x({title:`Hapus "${a.title}"?`,message:"Kartu ini hilang dari papan di semua device yang tersinkron.",confirmLabel:"Hapus tugas",tone:"danger",icon:"trash-2",run:()=>w.deleteTask(a.id)})&&(u("Tugas dihapus","ok","trash-2"),g(),d())}return t.jsxs(t.Fragment,{children:[t.jsxs(xe,{open:e,onClose:d,icon:"clipboard-list",eyebrow:"Papan tim",title:a?"Ubah tugas":"Tugas baru",footer:t.jsxs("div",{style:{display:"flex",gap:8,width:"100%",alignItems:"center"},children:[a&&t.jsx(B,{variant:"ghost",leftIcon:"trash-2",onClick:S,disabled:p,children:"Hapus"}),t.jsx("span",{style:{flex:1}}),t.jsx(B,{variant:"secondary",onClick:d,disabled:p,children:"Batal"}),t.jsx(B,{onClick:L,loading:p,children:a?"Simpan":"Buat tugas"})]}),children:[t.jsx($,{label:"Judul",children:t.jsx(O,{value:i.title,"aria-label":"Judul tugas",placeholder:"mis. Rapikan halaman harga",onChange:b=>k({title:b.target.value}),style:{width:"100%"}})}),t.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[t.jsx($,{label:"Project",children:t.jsx(M,{value:i.projectId,"aria-label":"Project tugas",onChange:b=>k({projectId:b.target.value}),options:[{value:"",label:"Tanpa project"},...n.map(b=>({value:b.id,label:b.name}))]})}),t.jsx($,{label:"Kolom",children:t.jsx(M,{value:i.status,"aria-label":"Kolom tugas",onChange:b=>k({status:b.target.value}),options:K.map(b=>({value:b.key,label:b.label}))})}),t.jsx($,{label:"Prioritas",children:t.jsx(M,{value:i.priority,"aria-label":"Prioritas tugas",onChange:b=>k({priority:b.target.value}),options:Kt})})]}),t.jsx($,{label:"Ditugaskan ke",children:t.jsx(M,{value:i.memberId,"aria-label":"Anggota tugas",onChange:b=>k({memberId:b.target.value}),options:[{value:"",label:"Belum ditugaskan"},...r.map(b=>({value:b.id,label:b.role?`${b.name} · ${b.role}`:b.name}))],style:{width:"100%"}})}),t.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[t.jsx($,{label:"Mulai",children:t.jsx(O,{type:"date",value:i.startDate,"aria-label":"Tanggal mulai",onChange:b=>k({startDate:b.target.value})})}),t.jsx($,{label:"Tenggat",children:t.jsx(O,{type:"date",value:i.dueDate,"aria-label":"Tanggal tenggat",onChange:b=>k({dueDate:b.target.value})})})]}),t.jsx($,{label:"Detail",hint:"Opsional — konteks yang tak muat di judul.",children:t.jsx(ot,{value:i.detail,"aria-label":"Detail tugas",rows:4,placeholder:"mis. tunggu aset dari klien, deadline ikut jadwal kampanye",onChange:b=>k({detail:b.target.value})})})]}),h]})}const Yt=dt.map(e=>({value:e,label:ct(e).label}));function Zt({task:e,projects:a,onClose:n,onDone:r,onToast:l}){const[o,d]=m.useState("brief"),[g,u]=m.useState(()=>Te.some(f=>f.value===e.priority)?e.priority:"sedang"),[i,c]=m.useState(""),[p,v]=m.useState(!1),x=e.projectId===null,h=e.projectId??i;async function y(){if(!(!h||p)){v(!0);try{const f=await w.escalateTask(e.id,{source:o,priority:g,...e.projectId?{}:{projectId:i}});l(f.created?`Dieskalasi jadi ${f.spec.id}`:`Sudah tertaut ke ${f.spec.id}`,"ok","link"),r(f.task),n()}catch{l("Gagal mengeskalasi kartu","err","x-circle")}finally{v(!1)}}}return t.jsxs(xe,{open:!0,onClose:p?void 0:n,icon:"git-branch",eyebrow:"Papan tim",title:"Eskalasi ke backlog",footer:t.jsxs("div",{style:{display:"flex",gap:8,width:"100%",alignItems:"center"},children:[t.jsx("span",{style:{flex:1}}),t.jsx(B,{variant:"secondary",onClick:n,disabled:p,children:"Batal"}),t.jsx(B,{onClick:y,loading:p,disabled:!h,leftIcon:"git-branch",children:"Eskalasi"})]}),children:[t.jsxs("div",{style:{fontSize:13.5,color:"var(--text-strong)",lineHeight:1.55,marginBottom:14},children:["Kartu ",t.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."]}),x&&t.jsxs($,{label:"Project",children:[t.jsx(M,{"aria-label":"Project",value:i,style:{width:"100%"},onChange:f=>c(f.target.value),options:[{value:"",label:"Pilih project…"},...a.map(f=>({value:f.id,label:f.name}))]}),t.jsx("div",{style:{marginTop:6,fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:"Nomor SPEC diambil dari repo project, jadi kartu tanpa project belum bisa dieskalasi."})]}),t.jsx($,{label:"Source",children:t.jsx(M,{"aria-label":"Source",value:o,style:{width:"100%"},onChange:f=>d(f.target.value),options:Yt})}),t.jsx($,{label:"Prioritas",children:t.jsx(M,{"aria-label":"Prioritas",value:g,style:{width:"100%"},onChange:f=>u(f.target.value),options:Te})})]})}function qt({m:e,busy:a,onSave:n,onToggle:r,onDelete:l}){const[o,d]=m.useState(!1),[g,u]=m.useState(e.name),[i,c]=m.useState(e.role??"");return o?t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8,padding:"12px 14px",marginBottom:8,border:"1px solid var(--border-strong)",borderRadius:"var(--radius-md)",background:"var(--surface-card)"},children:[t.jsx(O,{size:"sm",value:g,"aria-label":`Nama ${e.name}`,placeholder:"mis. Dena Meidina",onChange:p=>u(p.target.value)}),t.jsx(O,{size:"sm",value:i,"aria-label":`Peran ${e.name}`,placeholder:"mis. desainer",onChange:p=>c(p.target.value)}),t.jsxs("div",{style:{fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:[e.email," — ganti email berarti hapus lalu buat baru."]}),t.jsxs("div",{style:{display:"flex",gap:8},children:[t.jsx(B,{size:"sm",disabled:a,onClick:()=>{n(e.id,{name:g.trim(),role:i.trim()||null}),d(!1)},children:"Simpan"}),t.jsx(B,{size:"sm",variant:"ghost",onClick:()=>d(!1),children:"Batal"})]})]}):t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:10,padding:"10px 14px",marginBottom:8,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",background:"var(--surface-card)",opacity:e.active?1:.6},children:[t.jsxs("span",{style:{flex:1,minWidth:0},children:[t.jsxs("span",{style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{fontWeight:"var(--weight-semibold)",color:"var(--text-strong)"},children:e.name}),e.role&&t.jsx(ae,{tone:"neutral",size:"sm",children:e.role}),!e.active&&t.jsx(ae,{tone:"warn",size:"sm",children:"nonaktif"})]}),t.jsx("span",{style:{display:"block",fontFamily:"var(--font-mono)",fontSize:"var(--text-xs)",color:"var(--text-subtle)",marginTop:2},children:e.email})]}),t.jsx(de,{icon:"pencil",label:`Ubah ${e.name}`,size:"sm",onClick:()=>d(!0)}),t.jsx(de,{icon:e.active?"user-minus":"user-check",size:"sm",label:`${e.active?"Nonaktifkan":"Aktifkan"} ${e.name}`,onClick:()=>r(e)}),t.jsx(de,{icon:"trash-2",label:`Hapus ${e.name}`,size:"sm",onClick:()=>l(e)})]})}function Jt({open:e,onClose:a,onChanged:n,onToast:r}){const[l,o]=m.useState([]),[d,g]=m.useState("loading"),[u,i]=m.useState(!1),[c,p]=m.useState(""),[v,x]=m.useState(""),[h,y]=m.useState(""),{confirm:f,dialog:k}=Ue(),L=m.useRef(n);L.current=n;const S=m.useCallback(()=>{g("loading"),w.listMembers().then(j=>{o(j.items),g("ready"),L.current(j.items)}).catch(()=>g("error"))},[]);if(m.useEffect(()=>{e&&S()},[e,S]),!e)return null;async function b(){if(!c.trim()||!v.trim()){r("Nama & email wajib diisi","err","x-circle");return}i(!0);try{await w.createMember({name:c.trim(),email:v.trim(),role:h.trim()||null}),p(""),x(""),y(""),r("Anggota ditambahkan","ok","user-plus"),S()}catch{r("Gagal menambah anggota — email mungkin sudah terdaftar","err","x-circle")}finally{i(!1)}}async function D(j,P){i(!0);try{await w.patchMember(j,P),S()}catch{r("Gagal menyimpan anggota","err","x-circle")}finally{i(!1)}}async function C(j){i(!0);try{await w.patchMember(j.id,{active:!j.active}),S()}catch{r("Gagal mengubah status anggota","err","x-circle")}finally{i(!1)}}async function E(j){await f({title:`Hapus ${j.name} dari direktori?`,message:"Tugasnya tidak ikut terhapus — kartu yang ditugaskan padanya jadi 'belum ditugaskan'.",confirmLabel:"Hapus anggota",tone:"danger",icon:"trash-2",run:()=>w.deleteMember(j.id)})&&(r("Anggota dihapus","ok","trash-2"),S())}return t.jsxs(t.Fragment,{children:[t.jsxs(xe,{open:e,onClose:a,icon:"users",eyebrow:"Papan tim",title:"Anggota",width:620,children:[t.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",alignItems:"flex-end",marginBottom:16,paddingBottom:16,borderBottom:"1px solid var(--border-hair)"},children:[t.jsx(O,{size:"sm",value:c,"aria-label":"Nama anggota baru",placeholder:"Nama",onChange:j=>p(j.target.value),style:{flex:"1 1 140px"}}),t.jsx(O,{size:"sm",value:v,"aria-label":"Email anggota baru",placeholder:"email@nafanesia.id",onChange:j=>x(j.target.value),style:{flex:"1 1 180px"}}),t.jsx(O,{size:"sm",value:h,"aria-label":"Peran anggota baru",placeholder:"Peran (opsional)",onChange:j=>y(j.target.value),style:{flex:"1 1 130px"}}),t.jsx(B,{size:"sm",leftIcon:"user-plus",onClick:b,loading:u,children:"Tambah anggota"})]}),d==="loading"?t.jsx(H,{kind:"loading",compact:!0}):d==="error"?t.jsx(H,{kind:"error",compact:!0,hint:"Gagal memuat anggota.",action:S,actionLabel:"Coba lagi"}):l.length===0?t.jsx(H,{kind:"empty",compact:!0,icon:"users",title:"Belum ada anggota",hint:"Tambahkan orang di atas agar kartu papan bisa ditugaskan."}):l.map(j=>t.jsx(qt,{m:j,busy:u,onSave:D,onToggle:C,onDelete:E},j.id))]}),k]})}const Qt=5e3,Fe=200,Vt=400,We=[{value:"board",label:"Papan",icon:"kanban"},{value:"timeline",label:"Linimasa",icon:"gantt-chart"},{value:"projects",label:"Lintas project",icon:"layers"}],Xt={day:"Hari",week:"Minggu",month:"Bulan"},ea=()=>Object.fromEntries(K.map(e=>[e.key,0]));function ta({status:e,params:a,onData:n,refetch:r}){return ft({topic:"tasks",params:{...a,status:e},apply:l=>n(e,l.data.items,l.data.total),refetch:r,pollMs:Qt}),null}function la({projects:e,projectFilter:a,onProjectFilter:n,onToast:r}){const[l,o]=m.useState(vt),[d,g]=m.useState(ea),[u,i]=m.useState([]),[c,p]=m.useState("loading"),[v,x]=m.useState(!1),[h,y]=m.useState(null),[f,k]=m.useState(!1),[L,S]=m.useState(!1),[b,D]=m.useState(null),[C,E]=A("team","view","board",we(...We.map(s=>s.value))),[j,P]=A("team","q","",ce),[_,qe]=A("team","col","all",ce),[Z,Je]=A("team","member","all",ce),[ne,Qe]=A("team","zoom","week",we(...Le)),[Ve,be]=A("team","expanded",[],ht),Xe=m.useCallback(s=>{be(I=>I.includes(s)?I.filter(T=>T!==s):[...I,s])},[be]),ve=C==="timeline",N=C==="projects",ye=m.useRef(Date.now()).current,R=m.useMemo(()=>_==="all"?K:K.filter(s=>s.key===_),[_]),ie=R.map(s=>s.key).join(","),je=[a!=="all"&&!N,_!=="all",Z!=="all",j.trim()!==""].filter(Boolean).length,re=N||a==="all"?void 0:a,W=m.useMemo(()=>({projectId:re,memberId:Z==="all"?void 0:Z,q:j.trim()||void 0}),[re,Z,j]),te=m.useRef(!1),q=m.useCallback((s=!1)=>{!s&&!te.current&&p("loading");const I=ie?ie.split(","):[];Promise.all(I.map(T=>w.listTasks({...W,status:T,page:1,limit:Fe}))).then(T=>{o(z=>{const J={...z};return I.forEach((le,oe)=>{J[le]=T[oe].items}),J}),g(z=>{const J={...z};return I.forEach((le,oe)=>{J[le]=T[oe].total}),J}),te.current=!0,x(!1),p("ready")}).catch(()=>{if(!te.current){p("error");return}x(!0)})},[W,ie]);m.useEffect(()=>{q()},[q]);const ke=m.useCallback(()=>{w.listMembers().then(s=>i(s.items)).catch(()=>{})},[]);m.useEffect(()=>{ke()},[ke]);const[Se,et]=m.useState(()=>j.trim());m.useEffect(()=>{const s=setTimeout(()=>et(j.trim()),Vt);return()=>clearTimeout(s)},[j]);const tt=m.useCallback((s,I,T)=>{o(z=>({...z,[s]:I})),g(z=>({...z,[s]:T})),te.current=!0,x(!1),p("ready")},[]),at=m.useMemo(()=>({projectId:W.projectId,memberId:W.memberId,q:Se||void 0,page:1,limit:Fe}),[W.projectId,W.memberId,Se]),se=m.useCallback(()=>q(!0),[q]);async function nt(s,I){const T=yt(l,s.id,s.status,I);if(!T)return;const z=l;o(T.board);try{await w.patchTask(s.id,T.patch)}catch{o(z),r("Gagal memindahkan tugas","err","x-circle")}}async function it(s,I){const T=l;o(ue(l,{...s,memberId:I}));try{await w.patchTask(s.id,{memberId:I})}catch{o(T),r("Gagal menugaskan","err","x-circle")}}async function rt(s){const I=l;o(ue(l,{...s,specId:null,spec:null}));try{await w.unlinkTaskSpec(s.id),r("Tautan backlog dilepas","ok","unlink")}catch{o(I),r("Gagal melepas tautan","err","x-circle")}}const st=R.every(s=>l[s.key].length===0),Ie=m.useMemo(()=>R.flatMap(s=>l[s.key]),[l,R]),Ce=R.reduce((s,I)=>s+Math.max(0,(d[I.key]??0)-l[I.key].length),0);return t.jsxs("div",{style:ut,children:[t.jsxs("div",{className:"hn-team-controls",role:"region","aria-label":"Kontrol papan tim",style:{...G,marginBottom:18},children:[t.jsxs("div",{className:"hn-team-topline",style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:12,flexWrap:"wrap",marginBottom:12},children:[t.jsx(mt,{variant:"pill",value:C,onChange:E,tabs:We,"aria-label":"Mode tampilan"}),t.jsxs("div",{className:"hn-team-view-actions",style:{display:"flex",alignItems:"center",gap:10},children:[t.jsx(B,{size:"sm",leftIcon:"plus",onClick:()=>{y(null),k(!0)},children:"Tugas baru"}),t.jsx(B,{size:"sm",variant:"secondary",leftIcon:"users",onClick:()=>S(!0),children:"Anggota"}),t.jsx(pt,{onDone:se,onToast:r}),t.jsx(gt,{screen:"team",active:je,onReset:N?void 0:()=>n("all")}),t.jsxs("span",{className:"hn-eyebrow",role:"status",style:v?{color:"var(--amber-600)"}:void 0,title:v?"Server tak menjawab saat menyegarkan — angka ini dari muatan terakhir yang berhasil":void 0,children:[R.reduce((s,I)=>s+(d[I.key]??0),0)," tugas",v?" · basi":""]}),t.jsx(xt,{})]})]}),t.jsxs("div",{className:"hn-team-filters",style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[t.jsx(O,{size:"sm",leftIcon:"search","aria-label":"Cari tugas",value:j,placeholder:"mis. halaman harga atau deploy",onChange:s=>P(s.target.value),style:{flex:"1 1 220px"}}),t.jsx(M,{size:"sm","aria-label":"Filter project",value:a,disabled:N,onChange:s=>n(s.target.value),options:[{value:"all",label:"Semua project"},...e.map(s=>({value:s.id,label:s.name}))]}),N&&t.jsx("span",{"data-testid":"project-filter-note",style:{fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:"Mode ini melintasi semua project"}),t.jsx(M,{size:"sm","aria-label":"Filter kolom",value:_,onChange:s=>qe(s.target.value),options:[{value:"all",label:"Semua kolom"},...K.map(s=>({value:s.key,label:s.label}))]}),t.jsx(M,{size:"sm","aria-label":"Filter anggota",value:Z,onChange:s=>Je(s.target.value),options:[{value:"all",label:"Semua anggota"},...u.map(s=>({value:s.id,label:s.name}))]}),(ve||N)&&t.jsx(M,{size:"sm","aria-label":"Zoom linimasa",value:ne,onChange:s=>Qe(s.target.value),options:Le.map(s=>({value:s,label:Xt[s]}))})]})]}),R.map(s=>t.jsx(ta,{status:s.key,params:at,onData:tt,refetch:se},s.key)),c==="loading"?t.jsx(H,{kind:"loading"}):c==="error"?t.jsx(H,{kind:"error",hint:"Gagal memuat papan tim.",action:()=>q(),actionLabel:"Coba lagi"}):st&&je===0?t.jsx(H,{kind:"empty",icon:"users",title:"Papan tim masih kosong",hint:"Catat pekerjaan manusia di sekitar sesi agen — desain, meeting klien, deploy, nego.",action:()=>{y(null),k(!0)},actionLabel:"Tugas baru",actionIcon:"plus"}):N?t.jsx(Ht,{tasks:Ie,projects:e,members:u,zoom:ne,today:ye,hidden:Ce,expanded:Ve,onToggle:Xe,onOpen:s=>{y(s),k(!0)}}):ve?t.jsx(Ft,{tasks:Ie,members:u,zoom:ne,today:ye,hidden:Ce,onOpen:s=>{y(s),k(!0)}}):t.jsx(Pt,{board:l,totals:d,columns:R,members:u,onMove:nt,onAssign:it,onEscalate:D,onUnlink:rt,onOpen:s=>{y(s),k(!0)}}),t.jsx(Gt,{open:f,task:h,projects:e,members:u,defaultProjectId:re??null,orderFor:s=>He(l[s]),onClose:()=>{k(!1),y(null)},onSaved:se,onToast:r}),b&&t.jsx(Zt,{task:b,projects:e,onClose:()=>D(null),onDone:s=>o(I=>ue(I,s)),onToast:r}),t.jsx(Jt,{open:L,onClose:()=>S(!1),onChanged:i,onToast:r})]})}export{We as TEAM_VIEWS,la as TeamScreen};
@@ -1,2 +0,0 @@
1
- import{e as P,j as a,M as Se,d as Lt,S as Z,G as ga,J as Ft,f as nt,B as Ze,I as oe,w as xa,D as ba,a as K,K as va,N as ya,O as kt,Q as jt,c as Ue,U as ka,V as ja,W as wa,X as Sa,Y as Ia,Z as Ca,_ as Ie,$ as Bt,a0 as it,a1 as za,a2 as Ra,a3 as Ta,a4 as et,a5 as Ea,h as ke,a6 as Ot,a7 as Aa,a8 as Na,a9 as Da,aa as $a,g as Ye,ab as Pa,ac as La,ad as Mt,l as Fa,ae as wt,af as Ba,ag as Oa,x as Ma,ah as Wa,ai as _a,aj as Ve,p as Ka,ak as Ha,al as Ga,am as Wt,an as qa,ao as je,ap as Ua,aq as St,ar as Ya}from"./index-gNO91_qw.js";import{R as d,r as L}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.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 Pe=new Set;let we;function Va(e){return Pe.add(e),we||(we=setInterval(()=>{for(const i of[...Pe])i()},1e3)),()=>{Pe.delete(e),Pe.size===0&&we&&(clearInterval(we),we=void 0)}}const It=20;function Xa(e,i){if(!i)return"—";const r=new Date(i).getTime()-new Date(e).getTime();if(!Number.isFinite(r)||r<0)return"—";const s=Math.round(r/1e3);if(s<60)return`${s} dtk`;const o=Math.round(s/60);return o<60?`${o} mnt`:`${Math.floor(o/60)} jam ${o%60} mnt`}function Ja(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 _t=e=>rt(e)==="interrupted"?"—":Xa(e.startedAt,e.endedAt),Kt=e=>Ft[e]??e;function Qa({projects:e,onClose:i,onRestart:r}){const[s,o]=d.useState([]),[c,I]=d.useState(0),[h,R]=d.useState(1),[g,x]=d.useState(!1),[b,m]=d.useState(""),[y,T]=d.useState(""),[C,f]=d.useState(""),[z,E]=d.useState(""),[D,O]=d.useState(null);d.useEffect(()=>{const u=setTimeout(()=>E(C.trim()),250);return()=>clearTimeout(u)},[C]),d.useEffect(()=>{R(1)},[b,y,z]),d.useEffect(()=>{let u=!0;return x(!0),P.listSessionHistory({projectId:b||void 0,kind:y||void 0,q:z||void 0,page:h,limit:It}).then(v=>{u&&(I(v.total),o(v.items))}).catch(()=>{u&&(o([]),I(0))}).finally(()=>{u&&x(!1)}),()=>{u=!1}},[b,y,z,h]);const w=ba(c,h,It),N=u=>{var v;return((v=e.find(j=>j.id===u))==null?void 0:v.name)??u};return a.jsxs(Se,{open:!0,title:"Riwayat sesi",icon:"history",onClose:i,width:900,children:[a.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",marginBottom:10},children:[a.jsx(Lt,{size:"sm",leftIcon:"search",placeholder:"mis. spec-412 atau reverse","aria-label":"Cari riwayat sesi",value:C,onChange:u=>f(u.target.value),style:{flex:"1 1 200px"}}),a.jsx(Z,{size:"sm","aria-label":"Filter project",value:b,onChange:u=>m(u.target.value),options:[{value:"",label:"Semua project"}].concat(e.map(u=>({value:u.id,label:u.name})))}),a.jsx(Z,{size:"sm","aria-label":"Filter jenis",value:y,onChange:u=>T(u.target.value),options:[{value:"",label:"Semua jenis"}].concat(ga.map(u=>({value:u,label:Ft[u]})))})]}),s.length===0&&!g?a.jsx(nt,{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."}):a.jsxs("div",{style:{display:"flex",flexDirection:"column",maxHeight:"60vh",overflowY:"auto"},children:[s.map(u=>{const v=Ja(u);return a.jsx("button",{onClick:()=>O(u),style:{cursor:"pointer",display:"block",width:"100%",flex:"0 0 auto",font:"inherit",color:"inherit",textAlign:"left",background:"transparent",padding:"9px 8px",border:"none",borderBottom:"1px solid var(--border-hair)"},children:a.jsxs("span",{className:"hn-dense-row hn-picker-row",style:{display:"flex",alignItems:"center",gap:10,width:"100%"},children:[a.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",flex:"0 0 132px"},children:new Date(u.startedAt).toLocaleString("id-ID")}),a.jsx(Ze,{size:"sm",tone:"neutral",children:Kt(u.kind)}),a.jsx("span",{className:"hn-picker-title",style:{flex:1,minWidth:0,fontSize:13,color:"var(--text-strong)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:u.title??u.specId??N(u.projectId)}),u.transcriptBytes!==null&&a.jsx(oe,{name:"file-text",size:12,color:"var(--text-subtle)"}),a.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-muted)",flex:"0 0 72px"},children:_t(u)}),a.jsx(Ze,{size:"sm",tone:v.tone,children:v.label})]})},u.id)}),g&&a.jsx("div",{style:{padding:"10px 8px",textAlign:"center",fontSize:11,color:"var(--text-subtle)"},children:"memuat…"})]}),a.jsx(xa,{page:w.page,pageCount:w.pageCount,total:c,from:w.from,to:w.to,onPage:R,unit:"sesi"}),D&&a.jsx(Za,{row:D,projectName:N(D.projectId),onBack:()=>O(null),onRestart:r})]})}function Za({row:e,projectName:i,onBack:r,onRestart:s}){const[o,c]=d.useState(null),[I,h]=d.useState("idle");d.useEffect(()=>{if(e.transcriptBytes===null){h("none"),c(null);return}let x=!0;return h("loading"),P.sessionTranscript(e.id).then(b=>{x&&(c(b.text),h("idle"))}).catch(()=>{x&&(c(null),h("error"))}),()=>{x=!1}},[e.id,e.transcriptBytes]);const R=rt(e)==="interrupted",g=[["Project",i],["Sesi",e.sessionId],["Jenis",Kt(e.kind)],["Agen",[e.agent,e.model,e.effort].filter(Boolean).join(" · ")],["Mulai",new Date(e.startedAt).toLocaleString("id-ID")],[R?"Terakhir terlihat hidup":"Selesai",e.endedAt?new Date(e.endedAt).toLocaleString("id-ID"):"berjalan"],...R&&e.reconciledAt?[["Terdeteksi mati",new Date(e.reconciledAt).toLocaleString("id-ID")]]:[],["Durasi",_t(e)],["Direktori",e.cwd]];return e.specId&&g.splice(1,0,["Backlog",`${e.specId}${e.title?` · ${e.title}`:""}`]),e.branch&&g.push(["Branch",e.branch]),a.jsxs(Se,{open:!0,title:e.title??e.specId??e.sessionId,icon:"history",onClose:r,width:1e3,children:[a.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",marginBottom:10},children:[a.jsx(K,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:r,children:"Kembali"}),a.jsx("div",{style:{flex:1}}),o&&a.jsx(K,{size:"sm",variant:"secondary",leftIcon:"copy",onClick:()=>{var x;return void((x=navigator.clipboard)==null?void 0:x.writeText(o))},children:"Salin transkrip"}),va(e.kind)&&a.jsx(K,{size:"sm",leftIcon:"play",onClick:()=>s(e),children:"Mulai lagi"})]}),R&&a.jsxs(ya,{tone:"warn",title:"Sesi terputus — hasilnya tak diketahui",style:{marginBottom:12},children:["Panenya sudah lenyap saat hanoman menyala lagi (reboot, ",a.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."]}),a.jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"4px 12px",marginBottom:12,fontSize:12},children:g.map(([x,b])=>a.jsxs(d.Fragment,{children:[a.jsx("span",{style:{color:"var(--text-subtle)"},children:x}),a.jsx("span",{style:{fontFamily:"var(--font-mono)",color:"var(--text-body)",wordBreak:"break-all"},children:b})]},x))}),I==="loading"&&a.jsx("div",{style:{fontSize:12,color:"var(--text-subtle)"},children:"memuat transkrip…"}),I==="none"&&a.jsx("div",{style:{fontSize:12,color:"var(--text-subtle)"},children:R?"Tanpa transkrip — panenya sudah lenyap sebelum hanoman sempat mengambilnya.":"Tanpa transkrip — sesi ini ditutup sebelum fitur riwayat ada, atau panenya tak menyisakan keluaran."}),I==="error"&&a.jsx("div",{style:{fontSize:12,color:"var(--clay-600)"},children:"Transkrip tak terbaca lagi di server."}),o!==null&&a.jsx("pre",{style:{maxHeight:"52vh",overflow:"auto",margin:0,padding:10,background:"var(--bone-200)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",fontFamily:"var(--font-mono)",fontSize:11,whiteSpace:"pre-wrap",wordBreak:"break-word",color:"var(--text-body)"},children:o})]})}function en({open:e,projectId:i,projectName:r,onClose:s,onCreated:o}){var O;const[c,I]=d.useState("claude"),[h,R]=d.useState("sonnet"),[g,x]=d.useState("medium"),[b,m]=d.useState({claude:{model:"sonnet",effort:"medium"},codex:{...kt}}),[y,T]=d.useState(!1),[C,f]=d.useState(null);d.useEffect(()=>{e&&(P.getSettings().then(w=>{const N={claude:{model:w.model,effort:w.effort},codex:{...kt,...w.codex??{}}},u=w.agent==="codex"?"codex":"claude",v=jt(N,u);m(N),I(u),R(v.model),x(v.effort)}).catch(()=>{}),P.getCodexVersion().then(w=>f(w.version)).catch(()=>{}))},[e]);const z=w=>{I(w);const N=jt(b,w);R(N.model),x(N.effort)},E=w=>{R(w),x(N=>c==="codex"?Ia(w,N):Ca(w,N))};async function D(){T(!0);try{const{id:w}=await P.createTerminal(i,{agent:c,model:h,effort:g});o(w),s()}catch{}finally{T(!1)}}return a.jsxs(Se,{open:e,onClose:s,icon:"plus",eyebrow:r,title:"Sesi baru",footer:a.jsxs(a.Fragment,{children:[a.jsx(K,{variant:"ghost",onClick:s,children:"Batal"}),a.jsx(K,{leftIcon:"play",disabled:y,onClick:()=>void D(),children:"Buka sesi"})]}),children:[a.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Runtime untuk sesi ini. Default dari setelan global; ubah bila perlu. Sesi lahir dengan pilihan ini untuk seluruh hidupnya — ",a.jsx("code",{children:"/model"})," di terminal tetap bisa mengubahnya."]}),a.jsx(Ue,{label:"Agen",hint:"Mesin yang menjalankan sesi ini. Perilaku sesi sama; hanya CLI-nya berbeda.",children:a.jsx(Z,{"aria-label":"Agen",value:c,style:{width:"100%"},options:[{value:"claude",label:"Claude Code"},{value:"codex",label:"Codex CLI"}],onChange:w=>z(w.target.value)})}),a.jsx(Ue,{label:"Model",children:a.jsx(Z,{"aria-label":"Model",value:h,style:{width:"100%"},options:ka(c,h),onChange:w=>E(w.target.value)})}),a.jsx(Ue,{label:"Effort",children:a.jsx(Z,{"aria-label":"Effort",value:g,style:{width:"100%"},options:ja(c,h).map(w=>({value:w,label:w})),onChange:w=>x(w.target.value)})}),c==="codex"&&wa(h,C)&&a.jsxs("div",{"data-testid":"codex-version-note",style:{fontSize:12,lineHeight:1.5,marginBottom:12,padding:"8px 10px",borderRadius:8,background:"var(--warn-bg, #fdf6e3)",color:"var(--text-muted)"},children:["Codex CLI terpasang ",a.jsx("b",{children:C}),", sedangkan ",a.jsx("b",{children:h})," butuh ",a.jsx("b",{children:(O=Sa(h))==null?void 0:O.minClient}),". Sesi tetap boleh dijalankan, tapi modelnya belum tentu dikenali CLI ini."]})]})}const Ht=()=>({rows:1,cols:1,cells:[null]}),Gt=(e,i)=>[...e.slice(0,i),...e.slice(i+1)],Ct=e=>({...e,rows:e.rows+1,cells:[...e.cells,...Array(e.cols).fill(null)],...e.rowSizes?{rowSizes:[...e.rowSizes,1]}:{}});function zt(e){const i=e.cols+1,r=[];for(let s=0;s<e.rows;s++)for(let o=0;o<i;o++)r.push(o<e.cols?e.cells[s*e.cols+o]??null:null);return{...e,cols:i,cells:r,...e.colSizes?{colSizes:[...e.colSizes,1]}:{}}}function Rt(e,i){if(e.rows===1||i<0||i>=e.rows)return e;const r=[...e.cells];return r.splice(i*e.cols,e.cols),{...e,rows:e.rows-1,cells:r,...e.rowSizes?{rowSizes:Gt(e.rowSizes,i)}:{}}}function Tt(e,i){if(e.cols===1||i<0||i>=e.cols)return e;const r=e.cols-1,s=[];for(let o=0;o<e.rows;o++)for(let c=0;c<e.cols;c++)c!==i&&s.push(e.cells[o*e.cols+c]??null);return{...e,cols:r,cells:s,...e.colSizes?{colSizes:Gt(e.colSizes,i)}:{}}}const qt=.3,tn=(e,i,r)=>Math.min(r,Math.max(i,e));function st(e,i,r){if(i<0||i+1>=e.length||r===0)return e;const o=e.reduce((R,g)=>R+g,0)/e.length*qt,c=e[i]+e[i+1],I=tn(e[i]+r,o,c-o);if(I===e[i])return e;const h=[...e];return h[i]=I,h[i+1]=c-I,h}function Ut(e,i,r){const s=e.colSizes??Array(e.cols).fill(1),o=st(s,i,r);return o===s?e:{...e,colSizes:o}}function Yt(e,i,r){const s=e.rowSizes??Array(e.rows).fill(1),o=st(s,i,r);return o===s?e:{...e,rowSizes:o}}const an=.05,nn=.15,Vt=(e,i)=>e.reduce((r,s)=>r+s,0)*(i?nn:an);function rn(e,i,r,s=!1){const o=e.colSizes??Array(e.cols).fill(1);return Ut(e,i,r*Vt(o,s))}function sn(e,i,r,s=!1){const o=e.rowSizes??Array(e.rows).fill(1);return Yt(e,i,r*Vt(o,s))}function Et(e,i){const s=e.reduce((I,h)=>I+h,0)/e.length*qt,o=e[i]+e[i+1],c=Math.round(s/o*100);return{now:Math.round(e[i]/o*100),min:c,max:100-c}}function tt(e,i,r){if(i<0||i>=e.cells.length)return e;const s=e.cells.map(o=>r!==null&&o===r?null:o);return s[i]=r,{...e,cells:s}}const on=(e,i)=>({...e,cells:e.cells.map(r=>r&&i.has(r)?r:null)}),Xt=e=>({id:crypto.randomUUID(),name:e,layout:Ht()});function At(){const e=Xt("Utama");return{groups:[e],active:e.id}}const Ce=e=>e.groups.find(i=>i.id===e.active)??e.groups[0];function ln(e,i){const r=Xt(i);return{groups:[...e.groups,r],active:r.id}}const cn=(e,i,r)=>({...e,groups:e.groups.map(s=>s.id===i?{...s,name:r}:s)});function dn(e,i){if(e.groups.length===1)return e;const r=e.groups.filter(s=>s.id!==i);return r.length===e.groups.length?e:{groups:r,active:e.active===i?r[0].id:e.active}}const un=(e,i)=>e.groups.some(r=>r.id===i)?{...e,active:i}:e;function q(e,i){const r=Ce(e);return{...e,groups:e.groups.map(s=>s.id===r.id?{...s,layout:i(s.layout)}:s)}}function at(e,i,r){const s=Ce(e),o=r===null?e.groups:e.groups.map(c=>c.id===s.id?c:{...c,layout:tt(c.layout,c.layout.cells.indexOf(r),null)});return{...e,groups:o.map(c=>c.id===s.id?{...c,layout:tt(c.layout,i,r)}:c)}}function me(e,i){const r=Ce(e).layout.cells.indexOf(null);return r===-1?e:at(e,r,i)}const pn=(e,i)=>({...e,groups:e.groups.map(r=>({...r,layout:tt(r.layout,r.layout.cells.indexOf(i),null)}))}),Nt=e=>new Set(e.groups.flatMap(i=>i.layout.cells.filter(r=>r!==null))),Dt=(e,i)=>({...e,groups:e.groups.map(r=>({...r,layout:on(r.layout,i)}))}),Jt="hanoman.terminal.workspace",Qt="hanoman.terminal.layout",fe=e=>Ie.parse({version:1,groups:e.groups});function Le(e,i){const r=e.groups,s=i&&r.some(o=>o.id===i)?i:r[0].id;return{groups:r,active:s}}function mn(e){try{const i=JSON.parse(e);if(!i||typeof i!="object")return null;const r=i,s=Ie.parse({version:1,groups:r.groups});return{workspace:s,active:typeof r.active=="string"&&s.groups.some(o=>o.id===r.active)?r.active:s.groups[0].id}}catch{return null}}function fn(){try{const e=localStorage.getItem(Jt);if(e)return mn(e);const i=localStorage.getItem(Qt);if(!i)return null;const r=JSON.parse(i),s={id:crypto.randomUUID(),name:"Utama",layout:r};return{workspace:Ie.parse({version:1,groups:[s]}),active:s.id}}catch{return null}}function Xe(){try{localStorage.removeItem(Jt),localStorage.removeItem(Qt)}catch{}}const Zt=e=>`hanoman.terminal.workspace.v2.${encodeURIComponent(e)}`;function hn(e){try{const i=localStorage.getItem(Zt(e));if(!i)return null;const r=JSON.parse(i),s=Ie.parse(r.workspace);if(!Number.isInteger(r.revision)||(r.revision??-1)<0)return null;const o=typeof r.active=="string"&&s.groups.some(c=>c.id===r.active)?r.active:s.groups[0].id;return{workspace:s,revision:r.revision,active:o}}catch{return null}}function Je(e,i){try{const r=Ie.parse(i.workspace);if(!Number.isInteger(i.revision)||i.revision<0)return;const s=r.groups.some(o=>o.id===i.active)?i.active:r.groups[0].id;localStorage.setItem(Zt(e),JSON.stringify({workspace:r,revision:i.revision,active:s}))}catch{}}function Qe(e){if(!(e instanceof it)||e.status!==409)return null;const i=e.detail;if((i==null?void 0:i.code)!=="revision-conflict")return null;const r=za.safeParse(i.current);return r.success?r.data:null}function gn(e){const i=L.useRef(null);i.current||(i.current=At());const[r,s]=L.useState(i.current),[o,c]=L.useState("loading"),[I,h]=L.useState(null),[R,g]=L.useState(!1),x=L.useRef(r),b=L.useRef(0),m=L.useRef(!1),y=L.useRef(Promise.resolve()),T=L.useRef(0),C=L.useCallback(u=>{x.current=u,s(u)},[]),f=L.useCallback(u=>{m.current=u,g(u)},[]),z=L.useCallback(u=>{const v=y.current.then(u,u);return y.current=v.then(()=>{},()=>{}),v},[]),E=L.useCallback((u,v="ready",j=null,k=x.current.active)=>{const M=u.workspace?Le(u.workspace,k):At();b.current=u.revision,C(M),c(v),h(j),f(!0),u.workspace&&Je(e,{workspace:u.workspace,revision:u.revision,active:M.active})},[C,f,e]),D=L.useCallback(u=>{const v=hn(e);v&&(b.current=v.revision,C(Le(v.workspace,v.active))),f(!1),c("recovering"),h(u instanceof Error?u.message:"Layout server belum tersambung")},[C,f,e]),O=L.useCallback(()=>z(async()=>{try{E(await P.getTerminalWorkspace())}catch(u){D(u)}}),[E,z,D]);L.useEffect(()=>{const u=++T.current;return c("loading"),h(null),f(!1),z(async()=>{try{const v=await P.getTerminalWorkspace();if(u!==T.current)return;if(v.workspace){E(v),Xe();return}const j=fn();if(!j){E(v);return}try{const k=await P.putTerminalWorkspace({baseRevision:v.revision,workspace:j.workspace});if(u!==T.current)return;C(Le(k.workspace,j.active)),b.current=k.revision,Je(e,{workspace:k.workspace,revision:k.revision,active:j.active}),Xe(),c("ready"),h(null),f(!0)}catch(k){const M=Qe(k);M!=null&&M.workspace?(E(M,"conflict","Layout server lebih baru; layout lokal lama tidak diunggah"),Xe()):D(k)}}catch(v){u===T.current&&D(v)}}),()=>{T.current+=1}},[E,z,D,C,f,e]),L.useEffect(()=>{const u=()=>{O()},v=()=>{document.visibilityState==="visible"&&O()};return window.addEventListener("focus",u),document.addEventListener("visibilitychange",v),()=>{window.removeEventListener("focus",u),document.removeEventListener("visibilitychange",v)}},[O]);const w=L.useCallback(u=>z(async()=>{if(!m.current)return!1;const v=u(x.current);let j,k;try{j=fe(v),k=fe(x.current)}catch{return c("conflict"),h("Layout tidak valid dan tidak disimpan"),!1}if(Bt(j,k))return!0;try{return E(await P.putTerminalWorkspace({baseRevision:b.current,workspace:j}),"ready",null,v.active),!0}catch(M){const ee=Qe(M);if(!(ee!=null&&ee.workspace))return D(M),!1;const _=u(Le(ee.workspace,x.current.active));try{const U=await P.putTerminalWorkspace({baseRevision:ee.revision,workspace:fe(_)});return E(U,"conflict","Layout berubah di perangkat lain; perubahan ini diterapkan ulang",_.active),!0}catch(U){if(!Qe(U)&&!(U instanceof it&&U.status===409))return D(U),!1;try{E(await P.getTerminalWorkspace(),"conflict","Layout berubah lagi di perangkat lain; state terbaru dimuat")}catch(te){D(te)}return!1}}}),[E,z,D]),N=L.useCallback(u=>{const v=un(x.current,u);C(v);const j=fe(v);Je(e,{workspace:j,revision:b.current,active:v.active})},[C,e]);return{workspace:r,status:o,message:I,writable:R,mutate:w,setActive:N,refresh:O}}const xn=[];function Nn({userId:e="test-user",projects:i,backlog:r=xn,focusSession:s,startedSession:o,onStartedSessionHandled:c,onStartBacklog:I,onOpenReview:h,onOpenSessionReview:R,titleOf:g,onIntegrate:x,onIntegrateSession:b,specOf:m,sessions:y,setSessions:T}){var yt;const[C,f]=d.useState([]),z=y??C,E=T??f,[D,O]=d.useState([]),w=gn(e),{workspace:N,status:u,message:v,writable:j,mutate:k,setActive:M,refresh:ee}=w,[_,U]=ke("terminal","project",((yt=i[0])==null?void 0:yt.id)??"",Ka),te=Ot(),[le,ce]=ke("terminal","fontSize",te?Wa:_a,Ma),[Y,he]=ke("terminal","keys",te,Ve),[ae,ge]=ke("terminal","predict",!0,Ve),[J,ze]=ke("terminal","diag",!1,Ve),de=t=>ce(n=>Oa(n+t)),[B,Re]=d.useState(!1),[G,xe]=d.useState(null),[Te,ie]=d.useState(!1),[H,W]=d.useState(null),[Fe,be]=d.useState(!1),[Ee,Ae]=d.useState(!1),Be=Aa(),ot=Na(),ta=ot==="mobile",A=Ce(N).layout,Oe=A.rows===1&&A.cols===1&&!A.cells[0]&&z.length===0,Me=d.useRef(null),[aa,na]=d.useState(Number.POSITIVE_INFINITY);d.useEffect(()=>{const t=Me.current;if(!t||typeof ResizeObserver!="function")return;const n=new ResizeObserver(l=>{var S;const p=((S=l[0])==null?void 0:S.contentRect.width)??t.getBoundingClientRect().width;p>0&&na(p)});return n.observe(t),()=>n.disconnect()},[Oe]);const ia=ot==="tablet"&&Da(A.cols,aa,Ba),F=ta||ia,[Q,Ne]=d.useState(0),[ne,re]=d.useState(null),We=d.useRef(null),[ue,ra]=d.useState(!1);d.useEffect(()=>{P.listTerminals().then(t=>{E(t),ra(!0)}).catch(()=>{})},[]),d.useEffect(()=>$a(t=>{t.t==="sessions"&&!y?E(t.sessions):t.t==="cleanups"&&O(t.cleanups)}),[]),d.useEffect(()=>{if(!ue||!j)return;const t=new Set(z.map(l=>l.id)),n=Dt(N,t);Bt(fe(n),fe(N))||k(l=>Dt(l,t))},[k,z,ue,j,N]),d.useEffect(()=>{!o||o.specId==null||!ue||(E(t=>t.some(n=>n.id===o.id)?t:[...t,{...o,cwd:"",exited:!1}]),re(o.id),c==null||c())},[c,ue,o]),d.useEffect(()=>{if(!s){We.current=null;return}!ue||We.current===s||z.some(t=>t.id===s&&!t.exited)&&(We.current=s,re(s))},[s,z,ue]),d.useEffect(()=>{if(!ne)return;const t=N.groups.find(n=>n.layout.cells.includes(ne));if(t){t.id!==N.active&&M(t.id);return}j&&k(n=>{if(Nt(n).has(ne))return n;const l=me(n,ne);return l!==n||!F?l:at(n,Q,ne)})},[Q,F,k,ne,M,j,N]),d.useEffect(()=>{G&&!z.some(t=>t.id===G)&&xe(null)},[G,z]);const _e=D.filter(t=>t.error),De=t=>z.find(n=>n.id===t)??null,ve=d.useCallback(t=>{var n;return((n=i.find(l=>l.id===t))==null?void 0:n.name)??t},[i]);function sa(t){E(n=>n.some(l=>l.id===t)?n:[...n,{id:t,projectId:_,cwd:"",exited:!1}]),k(n=>me(n,t)),re(t)}async function lt(){if(!_)return;const{id:t}=await P.createShell(_);E(n=>[...n,{id:t,projectId:_,cwd:"",exited:!1}]),k(n=>me(n,t)),re(t)}async function ct(t,n){if(I&&!n){ie(!1),W(null),I(t);return}const l=Ga(t.source);try{const{id:p}=await P.startSession({spec:t.id,flow:l,...n?{force:n}:{}});E(S=>S.some($=>$.id===p)?S:[...S,{id:p,projectId:t.projectId,specId:t.id,flow:l,cwd:"",exited:!1}]),k(S=>me(S,p)),re(p),ie(!1),W(null)}catch(p){if(Be.offerRetry(p,t.id,$=>ct(t,$)))return;const S=p instanceof it&&(p.status===400||p.status===422);W(`${t.id} · gagal mulai${S?" · project belum punya repoDir":""}`)}}async function dt(t,n){try{const l=t.specId?await P.startSession({spec:t.specId,flow:t.flow??"feature",agent:t.agent==="codex"?"codex":"claude",...t.model?{model:t.model}:{},...t.effort?{effort:t.effort}:{},...n?{force:n}:{}}):t.kind==="shell"?await P.createShell(t.projectId):t.kind==="terminal"?await P.createTerminal(t.projectId,{agent:t.agent==="codex"?"codex":"claude",...t.model?{model:t.model}:{},...t.effort?{effort:t.effort}:{}}):await(n?P.createTerminalFlow(t.projectId,t.kind,{force:n}):P.createTerminalFlow(t.projectId,t.kind));E(p=>p.some(S=>S.id===l.id)?p:[...p,{id:l.id,projectId:t.projectId,specId:t.specId??void 0,cwd:"",exited:!1}]),k(p=>me(p,l.id)),re(l.id),Ae(!1)}catch(l){if((t.specId||t.kind!=="shell"&&t.kind!=="terminal")&&Be.offerRetry(l,`${t.projectId} · ${t.title??t.specId??t.kind}`,p=>dt(t,p)))return}}const ut=new Set(z.filter(t=>t.specId&&!t.exited).map(t=>t.specId)),oa=r.filter(t=>t.stage!=="done"&&!ut.has(t.id));function pt(t){E(n=>n.filter(l=>l.id!==t)),P.deleteTerminal(t).catch(()=>{})}const la=d.useCallback((t,n)=>{E(l=>l.map(p=>p.id===t?{...p,exited:!0,exitCode:n}:p))},[]),mt={close:pt,detach:t=>{k(n=>pn(n,t))},markExited:la,setFullId:xe,props:{onOpenReview:h,onOpenSessionReview:R,titleOf:g,onIntegrate:x,onIntegrateSession:b,specOf:m}},V=d.useRef(mt);V.current=mt;const ft=d.useRef(new Map),ca=t=>{let n=ft.current.get(t);return n||(n={onClose:()=>void V.current.close(t),onDetach:()=>V.current.detach(t),onExit:l=>V.current.markExited(t,l),onFullscreen:()=>V.current.setFullId(t)},ft.current.set(t,n)),n},pe=d.useRef({onOpenReview:t=>{var n,l;return(l=(n=V.current.props).onOpenReview)==null?void 0:l.call(n,t)},onOpenSessionReview:(t,n)=>{var l,p;return(p=(l=V.current.props).onOpenSessionReview)==null?void 0:p.call(l,t,n)},titleOf:t=>{var n,l;return(l=(n=V.current.props).titleOf)==null?void 0:l.call(n,t)},onIntegrate:(t,n,l)=>{var p,S;return(S=(p=V.current.props).onIntegrate)==null?void 0:S.call(p,t,n,l)},onIntegrateSession:(t,n,l)=>{var p,S;return(S=(p=V.current.props).onIntegrateSession)==null?void 0:S.call(p,t,n,l)},specOf:t=>{var n,l;return(l=(n=V.current.props).specOf)==null?void 0:l.call(n,t)}}).current,da=(t,n)=>{Ne(t),k(l=>at(l,t,n))},ua=t=>{re(t),k(n=>me(n,t))},pa=Nt(N),Ke=z.filter(t=>!pa.has(t.id));d.useEffect(()=>{if(!ne)return;const t=A.cells.indexOf(ne);t<0||(Ne(t),re(null))},[A.cells,ne]),d.useEffect(()=>{Q>=A.cells.length&&Ne(Math.max(0,A.cells.length-1))},[Q,A.cells.length]);const $e=d.useRef(null),[se,He]=d.useState(null),Ge=(se==null?void 0:se.axis)==="col"?se.sizes:A.colSizes??Array(A.cols).fill(1),qe=(se==null?void 0:se.axis)==="row"?se.sizes:A.rowSizes??Array(A.rows).fill(1);function ht(t,n,l){var $,X,ye;if(!j)return;const p=($=Me.current)==null?void 0:$.getBoundingClientRect();if(!p)return;(ye=(X=l.currentTarget).setPointerCapture)==null||ye.call(X,l.pointerId);const S=t==="col"?Ge:qe;$e.current={axis:t,index:n,pointerId:l.pointerId,start:t==="col"?l.clientX:l.clientY,extent:t==="col"?p.width:p.height,startSizes:S,latest:S},He({axis:t,sizes:S})}function gt(t){const n=$e.current;if(!n||n.pointerId!==t.pointerId)return;const l=n.axis==="col"?t.clientX:t.clientY,p=n.startSizes.reduce(($,X)=>$+X,0),S=(l-n.start)/n.extent*p;n.latest=st(n.startSizes,n.index,S),He({axis:n.axis,sizes:n.latest})}function xt(t){var l,p;const n=$e.current;!n||n.pointerId!==t.pointerId||($e.current=null,(p=(l=t.currentTarget).releasePointerCapture)==null||p.call(l,t.pointerId),He(null),n.latest!==n.startSizes&&k(S=>q(S,$=>n.axis==="col"?{...$,colSizes:n.latest}:{...$,rowSizes:n.latest})))}function bt(t,n,l){if(!j)return;const p=t==="col"?"ArrowRight":"ArrowDown",S=t==="col"?"ArrowLeft":"ArrowUp",$=l.key===p?1:l.key===S?-1:0;$!==0&&(l.preventDefault(),k(X=>q(X,ye=>t==="col"?rn(ye,n,$,l.shiftKey):sn(ye,n,$,l.shiftKey))))}function vt(t,n){j&&k(l=>q(l,p=>{const S=t==="col"?p.colSizes??Array(p.cols).fill(1):p.rowSizes??Array(p.rows).fill(1),X=(S[n]+S[n+1])/2-S[n];return t==="col"?Ut(p,n,X):Yt(p,n,X)}))}const ma=a.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:10,marginBottom:10},children:[a.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[a.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Ukuran teks terminal"}),a.jsx(Ye,{size:"sm",icon:"minus",label:"Perkecil teks terminal",disabled:le<=Pa,onClick:()=>de(-1)}),a.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,minWidth:44,textAlign:"center"},children:[le,"px"]}),a.jsx(Ye,{size:"sm",icon:"plus",label:"Perbesar teks terminal",disabled:le>=La,onClick:()=>de(1)})]}),a.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[a.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Papan tombol layar (Esc · panah · Enter)"}),a.jsx(K,{size:"sm",variant:"secondary","aria-pressed":Y,onClick:()=>he(t=>!t),children:Y?"Sembunyikan":"Tampilkan"})]}),a.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[a.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Ketik responsif (huruf tampil sebelum echo server)"}),a.jsx(K,{size:"sm",variant:"secondary","aria-pressed":ae,"aria-label":`${ae?"Matikan":"Nyalakan"} ketik responsif`,onClick:()=>ge(t=>!t),children:ae?"Matikan":"Nyalakan"})]}),a.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[a.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Rekam jalur ketik (diagnostik — merekam setiap tombol)"}),a.jsx(K,{size:"sm",variant:"secondary","aria-pressed":J,"aria-label":`${J?"Matikan":"Nyalakan"} rekam jalur ketik`,onClick:()=>ze(t=>!t),children:J?"Matikan":"Nyalakan"})]}),a.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[a.jsx("span",{id:"terminal-reset-grid-hint",style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:'Kembalikan grid ke 1 kolom × 1 baris (sesi lain pindah ke "belum di grid")'}),a.jsx(K,{size:"sm",variant:"secondary","aria-describedby":"terminal-reset-grid-hint",disabled:!j||A.cols===1&&A.rows===1,onClick:()=>void k(t=>q(t,()=>Ht())),children:"Reset grid"})]}),F&&a.jsx(Z,{size:"sm","aria-label":"Project sesi baru",value:_,onChange:t=>U(t.target.value),options:i.map(t=>({value:t.id,label:t.name}))})]}),fa=[{key:"backlog",label:"Ambil backlog",icon:"inbox",onSelect:()=>{W(null),ie(!0)}},{key:"history",label:"Riwayat sesi",icon:"history",onSelect:()=>Ae(!0)},{key:"shell",label:"Terminal biasa",icon:"terminal",onSelect:()=>void lt()},{key:"col+",label:"+ Kolom",icon:"columns-2",disabled:!j,onSelect:()=>void k(t=>q(t,zt))},{key:"row+",label:"+ Baris",icon:"rows-2",disabled:!j,onSelect:()=>void k(t=>q(t,Ct))},{key:"col-",label:"Hapus kolom aktif",icon:"columns-2",disabled:!j||A.cols===1,onSelect:()=>void k(t=>q(t,n=>Tt(n,Q%n.cols)))},{key:"row-",label:"Hapus baris aktif",icon:"rows-2",disabled:!j||A.rows===1,onSelect:()=>void k(t=>q(t,n=>Rt(n,Math.floor(Q/n.cols))))}],ha={display:"flex",flexDirection:"column",gap:B?8:12,...B?{position:"fixed",inset:0,zIndex:100,background:"var(--surface-page)",paddingTop:"max(12px, var(--safe-top))",paddingRight:"max(12px, var(--safe-right))",paddingBottom:"max(12px, var(--safe-bottom))",paddingLeft:"max(12px, var(--safe-left))"}:{flex:"1 1 0",minHeight:640}};return a.jsxs("div",{"data-testid":"terminal-root",style:ha,children:[a.jsxs("div",{style:{display:"flex",gap:8,flexDirection:B?"row":"column",alignItems:B?"center":"stretch"},children:[a.jsx(vn,{compact:B,ws:N,writable:j,onSelect:M,onAdd:()=>void k(t=>ln(t,`Grup ${t.groups.length+1}`)),onRename:(t,n)=>void k(l=>cn(l,t,n)),onRemove:t=>void k(n=>dn(n,t))}),a.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap",...B?{flex:1,minWidth:0}:{}},children:[!F&&a.jsxs(a.Fragment,{children:[a.jsx(K,{size:"sm",variant:"ghost",disabled:!j,onClick:()=>void k(t=>q(t,zt)),children:"+ Kolom"}),a.jsx(K,{size:"sm",variant:"ghost",disabled:!j,onClick:()=>void k(t=>q(t,Ct)),children:"+ Baris"})]}),a.jsx("div",{style:{flex:1,minWidth:0}}),u!=="ready"&&a.jsx("span",{"data-testid":"terminal-workspace-status",title:v??void 0,style:{fontSize:12,color:u==="conflict"?"var(--status-warn)":"var(--text-muted)"},children:u==="loading"?"Memuat layout server…":u==="recovering"?a.jsxs(a.Fragment,{children:[a.jsx("span",{children:"Layout server belum tersambung"})," ",a.jsx("button",{type:"button",onClick:()=>void ee(),children:"Retry"})]}):v??"Layout berubah di perangkat lain"}),D.length>0&&a.jsx("span",{"data-testid":"worktree-cleanups",title:D.map(t=>`${t.sessionId}${t.error?` — ${t.error}`:""}`).join(`
2
- `),style:{fontSize:12,color:_e.length?"var(--status-err)":"var(--text-muted)"},children:_e.length?`${_e.length} worktree gagal dibersihkan`:`membersihkan ${D.length} worktree…`}),!F&&a.jsxs(a.Fragment,{children:[a.jsx(Z,{size:"sm",value:_,onChange:t=>U(t.target.value),options:i.map(t=>({value:t.id,label:t.name}))}),a.jsx(K,{size:"sm",variant:"secondary",leftIcon:"inbox",onClick:()=>{W(null),ie(!0)},children:"Ambil backlog"}),a.jsx(K,{size:"sm",variant:"secondary",leftIcon:"history",title:"Riwayat sesi yang sudah berlalu — buka kembali atau baca transkripnya",onClick:()=>Ae(!0),children:"Riwayat"}),a.jsx(K,{size:"sm",variant:"secondary",leftIcon:"terminal",title:"Buka shell tmux tanpa Claude di project terpilih — jalankan command di project",onClick:()=>void lt(),children:"Terminal biasa"})]}),a.jsx(K,{size:"sm",leftIcon:"plus",onClick:()=>be(!0),children:"Sesi baru"}),a.jsx(Mt,{label:F?"Aksi terminal lain":"Tampilan terminal",items:F?fa:[],children:ma}),a.jsx(Ye,{size:"sm",icon:B?"minimize-2":"maximize-2",label:B?"Keluar layar penuh":"Layar penuh","aria-pressed":B,onClick:()=>Re(t=>!t)})]})]}),Ke.length>0&&a.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap",alignItems:"center"},children:[a.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"Belum di grid:"}),Ke.map(t=>a.jsxs("span",{className:"hn-terminal-unplaced-chip",style:{display:"inline-flex",alignItems:"center",borderRadius:"var(--radius-sm)",background:"var(--bone-200)",border:"1px solid var(--border-hair)",fontFamily:"var(--font-mono)",fontSize:11},children:[a.jsxs("button",{className:"hn-terminal-unplaced-action",disabled:!j,onClick:()=>ua(t.id),title:"Taruh di sel kosong pertama grup ini",style:{all:"unset",cursor:"pointer"},children:[t.specId??ve(t.projectId)," · ",t.id.slice(0,6)]}),a.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${t.id}`,onClick:()=>void pt(t.id),children:"×"})]},t.id))]}),F&&!Oe&&a.jsx("div",{className:"hn-stack-mobile",style:{display:"flex",alignItems:"center",gap:8},children:a.jsx(Fa,{"aria-label":"Panel terminal",variant:"pill",value:String(Q),onChange:t=>Ne(Number(t)),tabs:A.cells.map((t,n)=>({value:String(n),label:`Panel ${n+1}${t?` · ${t.slice(0,6)}`:" · kosong"}`}))})}),Oe?a.jsx(nt,{kind:"empty",icon:"terminal",title:"Belum ada sesi terminal",hint:"Pilih project lalu buka sesi — 'Sesi baru' menjalankan claude --dangerously-skip-permissions di direktori project; 'Terminal biasa' membuka shell tmux polos untuk menjalankan command."}):a.jsxs("div",{ref:Me,"data-testid":"terminal-grid",style:{flex:1,minHeight:0,display:"grid",gap:8,gridTemplateColumns:F?"minmax(0, 1fr)":`18px ${Ge.map(t=>`minmax(0, ${t}fr)`).join(" ")}`,gridTemplateRows:F?"minmax(0, 1fr)":`16px ${qe.map(t=>`minmax(0, ${t}fr)`).join(" ")}`},children:[!F&&a.jsx("div",{style:{gridColumn:1,gridRow:1}}),!F&&Array.from({length:A.cols},(t,n)=>a.jsx($t,{axis:"col",label:`Tutup kolom ${n+1}`,disabled:!j||A.cols===1,style:{gridColumn:n+2,gridRow:1},onClick:()=>void k(l=>q(l,p=>Tt(p,n)))},`col-${n}`)),!F&&Array.from({length:A.rows},(t,n)=>a.jsx($t,{axis:"row",label:`Tutup baris ${n+1}`,disabled:!j||A.rows===1,style:{gridColumn:1,gridRow:n+2},onClick:()=>void k(l=>q(l,p=>Rt(p,n)))},`row-${n}`)),!F&&Array.from({length:A.cols-1},(t,n)=>{const l=Et(Ge,n);return a.jsx(Pt,{orientation:"col",label:`Ubah lebar kolom ${n+1}/${n+2}`,now:l.now,min:l.min,max:l.max,disabled:!j,gridColumn:n+3,gridRow:"1 / -1",onPointerDown:p=>ht("col",n,p),onPointerMove:gt,onPointerUp:xt,onKeyDown:p=>bt("col",n,p),onDoubleClick:()=>vt("col",n)},`col-div-${n}`)}),!F&&Array.from({length:A.rows-1},(t,n)=>{const l=Et(qe,n);return a.jsx(Pt,{orientation:"row",label:`Ubah tinggi baris ${n+1}/${n+2}`,now:l.now,min:l.min,max:l.max,disabled:!j,gridColumn:"1 / -1",gridRow:n+3,onPointerDown:p=>ht("row",n,p),onPointerMove:gt,onPointerUp:xt,onKeyDown:p=>bt("row",n,p),onDoubleClick:()=>vt("row",n)},`row-div-${n}`)}),Array.from({length:A.rows},(t,n)=>n).flatMap(t=>Array.from({length:A.cols},(n,l)=>{const p=t*A.cols+l,S=A.cells[p]??null,$=S?De(S):null;return a.jsx("div",{"data-terminal-cell-index":p,"aria-hidden":F&&Q!==p?"true":"false",style:{minHeight:0,minWidth:0,display:F&&Q!==p?"none":"flex",flexDirection:"column",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden",...F?{}:{gridColumn:l+2,gridRow:t+2}},children:$?a.jsx(Sn,{session:$,nameOf:ve,...ca($.id),canArrange:j,onReview:h&&pe.onOpenReview,onSessionReview:R&&pe.onOpenSessionReview,titleOf:g&&pe.titleOf,onIntegrate:x&&pe.onIntegrate,onIntegrateSession:b&&pe.onIntegrateSession,specOf:m&&pe.specOf,backlog:r,fontSize:le,showKeys:Y,predict:ae,diag:J,fullscreen:G===$.id,paneHidden:F&&Q!==p}):a.jsx(zn,{disabled:!j,unplaced:Ke,nameOf:ve,onPick:X=>da(p,X)})},S??`empty-${p}`)}))]}),Te&&a.jsx(bn,{seed:oa,activeIds:ut,error:H,onPick:t=>void ct(t),onClose:()=>ie(!1)}),Fe&&a.jsx(en,{open:!0,projectId:_,projectName:ve(_),onClose:()=>be(!1),onCreated:sa}),Ee&&a.jsx(Qa,{projects:i,onClose:()=>Ae(!1),onRestart:t=>void dt(t)}),Be.dialog,G&&De(G)&&a.jsx(Cn,{session:De(G),label:ea(De(G),ve,g),fontSize:le,showKeys:Y,predict:ae,diag:J,onClose:()=>xe(null)})]})}function ea(e,i,r){const s=i(e.projectId),o=e.specId?r==null?void 0:r(e.specId):void 0;return e.specId?`${s} · ${e.specId}${o?` · ${o}`:""}`:e.id.startsWith("xaudit-")?`${s} · audit lintas`:s}function bn({seed:e,activeIds:i,error:r,onPick:s,onClose:o}){const[c,I]=d.useState(""),[h,R]=d.useState("all"),[g,x]=d.useState("all"),[b,m]=d.useState(e),[y,T]=d.useState("");d.useEffect(()=>{const f=setTimeout(()=>T(c.trim()),250);return()=>clearTimeout(f)},[c]),d.useEffect(()=>{var E,D;let f=!0;const z=(D=(E=P).listSpecs)==null?void 0:D.call(E,{startable:!0,q:y||void 0,stage:h==="all"?void 0:h,priority:g==="all"?void 0:g});return z==null||z.then(O=>{f&&m(O.items)}).catch(()=>{}),()=>{f=!1}},[y,h,g]);const C=b.filter(f=>!i.has(f.id));return a.jsxs(Se,{open:!0,title:"Ambil backlog",icon:"inbox",onClose:o,width:760,children:[r&&a.jsx("div",{style:{marginBottom:10,padding:"8px 10px",borderRadius:"var(--radius-sm)",background:"var(--clay-100)",color:"var(--clay-600)",fontSize:12},children:r}),a.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",marginBottom:10},children:[a.jsx(Lt,{size:"sm",leftIcon:"search",placeholder:"mis. invoice atau SPEC-412","aria-label":"Cari backlog",value:c,onChange:f=>I(f.target.value),style:{flex:"1 1 220px"}}),a.jsx(Z,{size:"sm","aria-label":"Filter stage",value:h,onChange:f=>R(f.target.value),options:[{value:"all",label:"Semua stage"}].concat(Ha.filter(f=>f.key!=="done").map(f=>({value:f.key,label:f.label})))}),a.jsx(Z,{size:"sm","aria-label":"Filter prioritas",value:g,onChange:f=>x(f.target.value),options:[{value:"all",label:"Semua prioritas"},{value:"tinggi",label:"Tinggi"},{value:"sedang",label:"Sedang"},{value:"rendah",label:"Rendah"}]})]}),C.length===0?a.jsx(nt,{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."}):a.jsx("div",{style:{display:"flex",flexDirection:"column",maxHeight:"62vh",overflowY:"auto"},children:C.map(f=>a.jsx("button",{onClick:()=>s(f),style:{cursor:"pointer",display:"block",width:"100%",flex:"0 0 auto",font:"inherit",color:"inherit",textAlign:"left",background:"transparent",padding:"9px 8px",border:"none",borderBottom:"1px solid var(--border-hair)"},children:a.jsxs("span",{className:"hn-dense-row hn-picker-row",style:{display:"flex",alignItems:"center",gap:10,width:"100%"},children:[a.jsx(oe,{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)"}),a.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-subtle)",flex:"0 0 78px"},children:f.id}),a.jsx("span",{className:"hn-picker-title",style:{flex:1,minWidth:0,fontSize:13,color:"var(--text-strong)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:f.title}),a.jsx(Ze,{tone:f.priority==="tinggi"?"err":"neutral",size:"sm",children:f.priority}),a.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,flex:"0 1 auto",minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"var(--text-muted)"},children:f.projectId})]})},f.id))})]})}function vn({ws:e,compact:i=!1,writable:r,onSelect:s,onAdd:o,onRename:c,onRemove:I}){const[h,R]=d.useState(null),g=Ce(e),x=e.groups.length===1;return a.jsxs("div",{role:"tablist","aria-label":"Grup terminal",style:{display:"flex",alignItems:"center",gap:4,flexWrap:"wrap",...i?{}:{borderBottom:"1px solid var(--border-hair)",paddingBottom:4}},children:[e.groups.map((b,m)=>{const y=b.id===g.id;return h===b.id?a.jsx(yn,{initial:b.name,onCommit:T=>{T.trim()&&c(b.id,T.trim()),R(null)},onCancel:()=>R(null)},b.id):a.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4,padding:"3px 6px",borderRadius:"var(--radius-sm)",fontSize:12,background:y?"var(--bone-200)":"transparent",border:`1px solid ${y?"var(--border-hair)":"transparent"}`},children:[a.jsx("button",{className:"hn-terminal-group-control",role:"tab","aria-selected":y,tabIndex:y?0:-1,onClick:()=>s(b.id),onKeyDown:T=>{var f,z;let C=null;T.key==="ArrowRight"?C=(m+1)%e.groups.length:T.key==="ArrowLeft"?C=(m-1+e.groups.length)%e.groups.length:T.key==="Home"?C=0:T.key==="End"&&(C=e.groups.length-1),C!==null&&(T.preventDefault(),s(e.groups[C].id),(z=(f=T.currentTarget.closest('[role="tablist"]'))==null?void 0:f.querySelectorAll('[role="tab"]')[C])==null||z.focus())},style:{border:0,padding:0,background:"transparent",font:"inherit",cursor:"pointer",color:y?"var(--text-strong)":"var(--text-muted)"},children:b.name}),y&&r&&a.jsxs(a.Fragment,{children:[a.jsx("button",{className:"hn-terminal-group-control","aria-label":`Ganti nama grup ${b.name}`,title:"Ganti nama",onClick:()=>R(b.id),style:{border:0,padding:0,background:"transparent",cursor:"pointer",color:"var(--text-subtle)",fontSize:10},children:"✎"}),a.jsx("button",{className:"hn-terminal-group-control","aria-label":`Hapus grup ${b.name}`,title:x?"Grup terakhir tak bisa dihapus":"Hapus grup (sesi tetap hidup)",disabled:x,onClick:()=>I(b.id),style:{border:0,padding:0,background:"transparent",cursor:x?"not-allowed":"pointer",color:"var(--text-subtle)",opacity:x?.35:1},children:"×"})]})]},b.id)}),a.jsx("button",{className:"hn-terminal-group-control","aria-label":"Grup baru",title:"Grup baru",disabled:!r,onClick:o,style:{border:0,background:"transparent",cursor:"pointer",padding:"3px 8px",color:"var(--text-subtle)",fontSize:12},children:"+"})]})}function $t({label:e,disabled:i,onClick:r,axis:s,style:o}){return a.jsx("button",{type:"button","aria-label":e,title:i?"Grid tak boleh menyusut ke nol":e,disabled:i,onClick:r,className:`hn-terminal-gutter hn-terminal-gutter--${s}`,style:{position:"relative",display:"grid",placeItems:"center",fontSize:11,lineHeight:1,opacity:i?.3:1,cursor:i?"not-allowed":"pointer",...o},children:"×"})}function Pt({orientation:e,label:i,now:r,min:s,max:o,disabled:c,gridColumn:I,gridRow:h,onPointerDown:R,onPointerMove:g,onPointerUp:x,onKeyDown:b,onDoubleClick:m}){return a.jsx("div",{role:"separator","aria-label":i,"aria-disabled":c,"aria-orientation":e==="col"?"vertical":"horizontal","aria-valuenow":r,"aria-valuemin":s,"aria-valuemax":o,tabIndex:c?-1:0,className:`hn-terminal-divider hn-terminal-divider--${e}`,title:c?void 0:"Seret untuk ubah ukuran — panah untuk langkah kecil, Shift+panah langkah besar, klik dua kali menyamakan",style:{gridColumn:I,gridRow:h},onPointerDown:c?void 0:R,onPointerMove:c?void 0:g,onPointerUp:c?void 0:x,onPointerCancel:c?void 0:x,onKeyDown:c?void 0:b,onDoubleClick:c?void 0:m})}function yn({initial:e,onCommit:i,onCancel:r}){const[s,o]=d.useState(e);return a.jsx("input",{autoFocus:!0,"aria-label":"Nama grup",value:s,placeholder:"mis. Rilis",onChange:c=>o(c.target.value),onBlur:()=>i(s),onKeyDown:c=>{c.key==="Enter"?i(s):c.key==="Escape"&&r()},style:{width:"min(160px, 60vw)",padding:"3px 6px",fontSize:12,fontFamily:"var(--font-ui)",border:"1px solid var(--border-strong)",borderRadius:"var(--radius-sm)",background:"var(--surface-card)",color:"var(--text-strong)"}})}const kn={done:"var(--brass)",active:"var(--text-strong)",skipped:"var(--text-subtle)",pending:"var(--text-subtle)"},jn={done:"✓",running:"●",pending:"○",skipped:"–",failed:"✕",abandoned:"⨯"};function wn({phases:e,compact:i=!1,now:r}){const[s,o]=d.useState(null),c=Ra(s!==null,()=>o(null),"dialog"),[,I]=d.useState(0),h=!!(e!=null&&e.some(m=>{var y;return((y=m.agent)==null?void 0:y.status)==="running"}));if(d.useEffect(()=>{if(!(!h||r!==void 0))return Va(()=>I(m=>m+1))},[h,r]),!(e!=null&&e.length))return null;const R=r??Date.now(),g=e.find(m=>m.name===s&&m.agent),x=m=>({color:kn[m.state],fontWeight:m.state==="active"?600:400,textDecoration:m.state==="skipped"?"line-through":"none",opacity:m.state==="pending"?.5:1}),b=m=>{const y=m.agent;return y?typeof y.durationMs=="number"?wt(y.durationMs):y.status==="running"&&y.startedAt?wt(R-Date.parse(y.startedAt)):"":""};return a.jsxs("div",{"data-testid":"phase-strip",style:{flex:"0 0 auto",borderBottom:"1px solid var(--border-hair)"},children:[a.jsx("div",{"data-testid":"phase-strip-scroller",style:{display:"flex",alignItems:"center",gap:8,padding:"3px 8px",fontSize:10,fontFamily:"var(--font-mono)",overflowX:"auto",whiteSpace:"nowrap"},children:e.map(m=>{if(!m.agent)return a.jsx("span",{"data-state":m.state,title:m.state,style:x(m),children:m.name},m.name);const y=m.agent,T=Ta(m),C=!i||m.state==="active",f=b(m);return a.jsxs("button",{type:"button","data-tone":T,"aria-expanded":s===m.name,ref:s===m.name?c.triggerRef:void 0,"aria-haspopup":"dialog","aria-controls":s===m.name?c.panelId:void 0,"aria-label":Ea(m,f),onClick:()=>o(s===m.name?null:m.name),style:{display:"inline-flex",alignItems:"center",gap:4,flex:"0 0 auto",padding:"1px 6px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",background:"transparent",font:"inherit",color:"var(--text-body)",cursor:"pointer"},children:[a.jsx("span",{"aria-hidden":!0,children:jn[T]}),a.jsx("span",{"data-state":m.state,title:m.state,style:x(m),children:m.name}),m.state==="skipped"&&a.jsx("span",{children:"dilewati"}),C&&y.model&&a.jsxs("span",{children:["· ",et(y.model)]}),C&&y.effort&&a.jsxs("span",{children:["· ",y.effort]}),C&&f&&a.jsxs("span",{children:["· ",f]}),y.attempts>1&&a.jsxs("span",{children:["↻",y.attempts]}),y.evidence==="missing"&&a.jsx("span",{role:"img","aria-label":"bukti subagent tak diterima",title:"bukti subagent tak diterima",style:{color:"var(--status-warn)"},children:"⚠"})]},m.name)})}),(g==null?void 0:g.agent)&&a.jsxs("div",{ref:c.panelRef,id:c.panelId,role:"dialog","aria-label":`Detail fase ${g.name}`,tabIndex:-1,onKeyDown:c.onKeyDown,style:{position:"absolute",marginLeft:8,zIndex:5,minWidth:220,maxWidth:"min(420px, calc(100% - 16px))",maxHeight:"calc(100% - 48px)",overflowY:"auto",boxSizing:"border-box",padding:"8px 10px",background:"var(--surface-card)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",whiteSpace:"normal",lineHeight:1.5,fontSize:10,fontFamily:"var(--font-mono)"},children:[a.jsx("div",{children:a.jsx("b",{children:g.agent.name})}),a.jsx("div",{children:[et(g.agent.model),g.agent.effort,g.agent.status??"belum mulai"].filter(Boolean).join(" · ")}),a.jsxs("div",{children:["durasi ",b(g)||"—"," · percobaan ",g.agent.attempts]}),a.jsxs("div",{children:["token in ",g.agent.inputTokens??"—"," · out ",g.agent.outputTokens??"—"," · cache ",g.agent.cachedTokens??"—"]}),g.agent.resultExcerpt&&a.jsx("pre",{style:{margin:"6px 0 0",whiteSpace:"pre-wrap",maxHeight:160,overflow:"auto"},children:g.agent.resultExcerpt})]})]})}const Sn=d.memo(In);function In({session:e,nameOf:i,onClose:r,canArrange:s,onDetach:o,onExit:c,onReview:I,onSessionReview:h,titleOf:R,onIntegrate:g,onIntegrateSession:x,specOf:b,fontSize:m,showKeys:y,predict:T,diag:C,fullscreen:f,onFullscreen:z,paneHidden:E}){const[D,O]=d.useState(null),w=d.useRef(null),[N,u]=d.useState(Number.POSITIVE_INFINITY),v=Ot();d.useEffect(()=>{const H=w.current;if(!H||typeof ResizeObserver!="function")return;const W=new ResizeObserver(Fe=>{var Ee;const be=((Ee=Fe[0])==null?void 0:Ee.contentRect.width)??H.getBoundingClientRect().width;be>0&&u(be)});return W.observe(H),()=>W.disconnect()},[]);const[j,k]=d.useState(!1),M=d.useCallback((H,W)=>{O(H),k(W)},[]),[ee,_]=d.useState(!1),[U,te]=d.useState(!1),[le,ce]=d.useState(!1),Y=e.specId?b==null?void 0:b(e.specId):void 0,he=!e.specId&&!!e.branch,ae=ea(e,i,R),ge=!e.exited&&!!e.decision,J=!e.exited&&!!e.deciding,ze=ge||J,de=e.exited&&!!e.exitCode,B=!e.exited&&j,Re=de?null:e.exited||B?"PST-005":ze?"PST-004":"PST-003",G=[...e.specId?[{key:"docs",label:"Lihat dokumen",icon:"file-text",title:"Lihat dokumen (audit/spec/plan)",onSelect:()=>_(!0),render:a.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>_(!0),"aria-label":`Lihat dokumen sesi ${e.id}`,title:"Lihat dokumen (audit/spec/plan)",children:a.jsx(oe,{name:"file-text",size:12})},"docs")}]:[],...e.specId&&I?[{key:"review",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree)",onSelect:()=>I(e.specId),render:a.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>I(e.specId),"aria-label":`Review sesi ${e.id}`,title:"Review perubahan (diff worktree)",children:a.jsx(oe,{name:"git-compare",size:12})},"review")}]:[],...he&&h?[{key:"review-session",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree sesi)",onSelect:()=>h(e.id,ae),render:a.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>h(e.id,ae),"aria-label":`Review sesi ${e.id}`,title:"Review perubahan (diff worktree sesi)",children:a.jsx(oe,{name:"git-compare",size:12})},"review-session")}]:[],...Y&&g?[{key:"integrate",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch spec",onSelect:()=>te(!0),render:a.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>te(!0),"aria-label":`Integrasikan sesi ${e.id}`,title:"Rebase / Merge branch spec",children:a.jsx(oe,{name:"git-merge",size:12})},"integrate")}]:[],...he&&x?[{key:"integrate-session",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch sesi",onSelect:()=>ce(!0),render:a.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>ce(!0),"aria-label":`Integrasikan sesi ${e.id}`,title:"Rebase / Merge branch sesi",children:a.jsx(oe,{name:"git-merge",size:12})},"integrate-session")}]:[],{key:"detach",label:"Lepas dari grid",icon:"unlink",disabled:!s,title:"Lepas dari grid (sesi tetap hidup)",onSelect:o,render:a.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:o,disabled:!s,title:"Lepas dari grid (sesi tetap hidup)",children:"lepas"},"detach")},{key:"fullscreen",label:"Layar penuh",icon:"fullscreen",title:"Layar penuh — fokus 1 terminal",onSelect:z,render:a.jsx("button",{type:"button",className:"hn-terminal-action",onClick:z,title:"Layar penuh — fokus 1 terminal","aria-label":`Layar penuh sesi ${e.id}`,children:a.jsx(oe,{name:"fullscreen",size:12})},"fullscreen")},{key:"close",label:"Tutup",icon:"x",title:"Tutup sesi",onSelect:r,render:a.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${e.id}`,onClick:r,children:"×"},"close")}],xe=40+(e.orchestrated&&e.model?110:0)+(e.exited||B?110:0)+(J||ge&&!B?130:0),Te=Ya(N,G.length,v?44:28,xe),ie=G.slice(Te);return a.jsxs(a.Fragment,{children:[a.jsxs("div",{ref:w,className:"hn-terminal-cell-header",style:{display:"flex",alignItems:"center",gap:8,padding:"4px 8px",flex:"0 0 auto",background:de?"var(--status-err-tint)":e.exited||B?"var(--status-ok-tint)":ze?"var(--status-warn-tint)":"var(--bone-200)",borderBottom:"1px solid var(--border-hair)",fontFamily:"var(--font-mono)",fontSize:11,color:e.exited?"var(--text-muted)":"var(--text-body)"},children:[Re&&a.jsx(qa,{id:Re,decorative:!0,style:{width:34,flex:"0 0 auto",borderRadius:"var(--radius-sm)"}}),a.jsxs("span",{style:{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:[ae," · ",e.id.slice(0,6)]}),e.orchestrated&&e.model&&a.jsxs("span",{"data-testid":"orchestrator-chip",title:"Model & effort orchestrator",style:{flex:"0 0 auto",fontSize:10,color:"var(--text-muted)"},children:["orch ",et(e.model),e.effort?` · ${e.effort}`:""]}),e.exited&&(de?a.jsx(je,{status:"failed",size:"sm",children:`Gagal · exit ${e.exitCode}`}):a.jsx(je,{status:"done",size:"sm",children:"Selesai"})),B&&a.jsx(je,{status:"done",size:"sm",children:"Selesai"}),J&&!B&&a.jsx(je,{status:"running",size:"sm",children:"Lead memutuskan"}),ge&&!J&&!B&&a.jsx(je,{status:"awaiting",size:"sm"}),a.jsxs("span",{className:"hn-terminal-actions",children:[G.slice(0,Te).map(H=>H.render),ie.length>0&&a.jsx(Mt,{label:`Aksi lain sesi ${e.id}`,items:ie.map(({render:H,...W})=>W)})]})]}),a.jsxs("div",{style:{display:"flex",flexDirection:"column",flex:1,minHeight:0,position:"relative",opacity:e.exited?.6:1},children:[a.jsx(wn,{phases:D,compact:N<480}),a.jsx("div",{style:{flex:1,minHeight:0},children:f?a.jsx("div",{style:{height:"100%",display:"grid",placeItems:"center",padding:12,color:"var(--text-subtle)",fontSize:12,textAlign:"center"},children:"Terbuka di layar penuh"}):a.jsx(Wt,{sessionId:e.id,onExit:c,onPhases:M,fontSize:m,showKeys:y,predict:T,diag:C,hidden:E},e.id)})]}),ee&&e.specId&&a.jsx(Ua,{specId:e.specId,onClose:()=>_(!1)}),U&&Y&&g&&a.jsx(St,{projectId:Y.projectId,ownBranch:`hanoman/${Y.id.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,eyebrow:Y.id,onClose:()=>te(!1),onIntegrate:(H,W)=>{te(!1),g(Y,H,W)}}),le&&he&&x&&a.jsx(St,{projectId:e.projectId,ownBranch:e.branch,eyebrow:e.id.slice(0,16),onClose:()=>ce(!1),onIntegrate:(H,W)=>{ce(!1),x(e,H,W)}})]})}function Cn({session:e,label:i,fontSize:r,showKeys:s,predict:o,diag:c,onClose:I}){return a.jsx(Se,{open:!0,icon:"terminal",title:i,onClose:I,closeOnEscape:!1,width:1600,children:a.jsx("div",{style:{height:"min(72vh, calc(100dvh - 180px))",minHeight:0,display:"flex",flexDirection:"column",opacity:e.exited?.6:1},children:a.jsx(Wt,{sessionId:e.id,onExit:()=>{},fontSize:r,showKeys:s,predict:o,diag:c},e.id)})})}function zn({unplaced:e,nameOf:i,onPick:r,disabled:s}){return a.jsx("div",{style:{flex:1,display:"grid",placeItems:"center",padding:12},children:a.jsx(Z,{size:"sm",value:"","aria-label":"Pilih sesi untuk sel",disabled:s||!e.length,onChange:o=>o.target.value&&r(o.target.value),options:[{value:"",label:e.length?"Pilih sesi…":"tidak ada sesi bebas"}].concat(e.map(o=>({value:o.id,label:`${o.specId??i(o.projectId)} · ${o.id.slice(0,6)}`})))})})}export{wn as PhaseStrip,Nn as TerminalScreen};
@@ -1 +0,0 @@
1
- import{e as y,j as e,a as d,f as T,B as C,h as H,o as V,r as Y,t as X,q as Z,S as F,d as U,m as ee,R as te,v as ae,w as ie,p as A,x as se,I as le,y as ne,u as re,c as W,H as oe,z as O,A as q,C as ce,D as de}from"./index-gNO91_qw.js";import{R as l}from"./react-DfGhg7ZW.js";import{L as ue}from"./live-Cz6dWAau.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";function pe(s,c){return s==="rejected"?"Ditutup":s!=="accepted"?"Sedang ditinjau":c==="done"?"Selesai":c==="executing"?"Sedang dikerjakan":"Diterima"}const he=5e3,$=20,me=400;function M({total:s,page:c,onPage:j,unit:p="tiket"}){const n=de(s,c,$);return e.jsx(ie,{page:n.page,pageCount:n.pageCount,total:s,from:n.from,to:n.to,onPage:j,unit:p})}function Q(s,c=Date.now()){const j=Math.max(0,c-new Date(s).getTime()),p=Math.floor(j/6e4);if(p<1)return"baru saja";if(p<60)return`${p}m`;const n=Math.floor(p/60);return n<24?`${n}j`:`${Math.floor(n/24)}h`}const K={new:"warn",accepted:"ok",rejected:"neutral"},J={new:"belum ditinjau",accepted:"diterima",rejected:"ditutup"};function ge({t:s,onOpen:c}){return e.jsxs("button",{onClick:()=>c(s.id),className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:12,width:"100%",textAlign:"left",padding:"12px 14px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",background:"var(--surface-card)",cursor:"pointer",marginBottom:8},children:[e.jsxs("span",{style:{flex:1,minWidth:0},children:[e.jsxs("span",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:["#",s.number]}),e.jsx(C,{tone:"neutral",size:"sm",children:s.category}),e.jsx(C,{tone:K[s.status]??"neutral",size:"sm",children:J[s.status]??s.status})]}),e.jsx("span",{style:{display:"block",color:"var(--text-body)",fontSize:"var(--text-sm)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:s.title}),e.jsxs("span",{style:{fontSize:"var(--text-xs)",color:"var(--text-subtle)",marginTop:2,display:"block"},children:[s.projectId," · ",s.reporterEmail," · ",Q(s.createdAt)," lalu",s.attachmentCount>0?` · ${s.attachmentCount} lampiran`:""]})]}),s.specId&&e.jsxs(C,{tone:"ok",icon:"link",children:["→ ",s.specId]}),e.jsx(le,{name:"chevron-right",size:16,color:"var(--text-subtle)"})]})}function xe({id:s,onBack:c,onAccepted:j,onDeleted:p,onToast:n}){var R;const[i,k]=l.useState(null),[h,z]=l.useState("loading"),[m,u]=l.useState(!1),[g,x]=l.useState("sedang"),[P,b]=l.useState(!1),[f,B]=l.useState(!1),{confirm:v,dialog:S}=re(),[r,I]=l.useState({title:"",detail:"",category:"bug",status:"new"}),w=l.useCallback(()=>{y.getTicket(s).then(t=>{k(t),z("ready")}).catch(()=>z("error"))},[s]);if(l.useEffect(()=>{w()},[w]),h==="loading")return e.jsx(T,{kind:"loading"});if(h==="error"||!i)return e.jsx(T,{kind:"error",hint:"Gagal memuat tiket.",action:w,actionLabel:"Coba lagi"});async function L(){u(!0);try{const t=await y.acceptTicket(s,g);j(t.spec,!!t.alreadyPromoted)}catch{n("Gagal menerima tiket","err","x-circle")}finally{u(!1)}}async function E(){if(await v({title:`Tolak & tutup tiket #${i.number}?`,message:`"${i.title}" ditutup tanpa membuat backlog item.`,confirmLabel:"Tolak tiket",icon:"x-circle"})){u(!0);try{await y.rejectTicket(s),k({...i,status:"rejected"}),n("Tiket ditutup","ok","check")}catch{n("Gagal menolak tiket","err","x-circle")}finally{u(!1)}}}async function a(){u(!0);try{const t=await y.unlinkTicket(s);k({...i,specId:t.specId,spec:null,status:t.status}),n("Tautan backlog dilepas","ok","unlink")}catch{n("Gagal melepas tautan","err","x-circle")}finally{u(!1)}}function o(){I({title:i.title,detail:i.detail,category:i.category,status:i.status}),b(!0)}async function D(){u(!0);try{const t=await y.editTicket(s,{title:r.title,detail:r.detail,category:r.category,status:r.status});k(t),b(!1),n("Tiket diperbarui","ok")}catch{n("Gagal menyimpan","err","x-circle")}finally{u(!1)}}async function N(){u(!0);try{await y.deleteTicket(s),n("Tiket dihapus","ok","trash-2"),p()}catch{n("Gagal menghapus","err","x-circle"),u(!1)}}if(P)return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10},children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:()=>b(!1),disabled:m,children:"Batal"}),e.jsx("span",{style:{flex:1}}),e.jsx(d,{size:"sm",variant:"primary",leftIcon:"check",onClick:D,disabled:m,children:"Simpan"})]}),e.jsx(W,{label:"Judul",children:e.jsx(U,{value:r.title,placeholder:"mis. Tombol Simpan tak berfungsi di HP",onChange:t=>I({...r,title:t.target.value})})}),e.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[e.jsx(W,{label:"Kategori",children:e.jsx(F,{value:r.category,onChange:t=>I({...r,category:t.target.value}),options:[{value:"bug",label:"bug"},{value:"fitur",label:"fitur"},{value:"pertanyaan",label:"pertanyaan"},{value:"lainnya",label:"lainnya"}]})}),e.jsx(W,{label:"Status",children:e.jsx(F,{value:r.status,onChange:t=>I({...r,status:t.target.value}),options:[{value:"new",label:"belum ditinjau"},{value:"accepted",label:"diterima"},{value:"rejected",label:"ditutup"}]})})]}),e.jsx(W,{label:"Detail keluhan",children:e.jsx(oe,{value:r.detail,rows:6,placeholder:"mis. Buka halaman Pesanan di HP, tekan Simpan — layar diam dan datanya tak tersimpan.",onChange:t=>I({...r,detail:t.target.value})})})]});const _=i.status!=="new";return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:c,children:"Kembali"}),e.jsx(C,{tone:K[i.status]??"neutral",children:J[i.status]??i.status}),e.jsx("span",{style:{flex:1}}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"pencil",onClick:o,disabled:m,children:"Ubah"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"trash-2",onClick:()=>B(!0),disabled:m,children:"Hapus"}),i.publicStatusUrl&&e.jsxs(e.Fragment,{children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"share-2",onClick:()=>window.open(i.publicStatusUrl,"_blank","noreferrer"),children:"Buka status publik"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"link-2",onClick:()=>{var t;(t=navigator.clipboard)==null||t.writeText(i.publicStatusUrl),n("Link publik disalin","ok","copy")},children:"Salin link publik"})]}),i.specId?e.jsxs(e.Fragment,{children:[e.jsxs(C,{tone:"ok",icon:"link",children:["→ ",i.specId]}),e.jsx(C,{tone:"neutral",size:"sm",children:pe(i.status,(R=i.spec)==null?void 0:R.stage)}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"external-link",onClick:()=>window.open(O(i.specId),"_blank","noreferrer"),children:"Buka backlog"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"copy",onClick:()=>{var t;(t=navigator.clipboard)==null||t.writeText(O(i.specId)),n("Link backlog disalin","ok","copy")},children:"Salin link"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"unlink",onClick:a,disabled:m,children:"Lepas tautan"})]}):!_&&e.jsxs(e.Fragment,{children:[e.jsx(F,{size:"sm",value:g,onChange:t=>x(t.target.value),options:[{value:"tinggi",label:"Prioritas tinggi"},{value:"sedang",label:"Prioritas sedang"},{value:"rendah",label:"Prioritas rendah"}]}),e.jsx(d,{size:"sm",leftIcon:"arrow-up-right",onClick:L,disabled:m,children:"Terima → backlog"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"ban",onClick:E,disabled:m,children:"Tolak"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:["#",i.number]}),e.jsx(C,{tone:"neutral",size:"sm",children:i.category})]}),e.jsx("div",{style:{fontWeight:600,fontSize:"var(--text-lg)",color:"var(--text-strong)",marginTop:4},children:i.title})]}),e.jsxs("div",{style:{display:"flex",gap:18,flexWrap:"wrap",fontSize:"var(--text-sm)",color:"var(--text-muted)"},children:[e.jsxs("span",{children:["pelapor: ",e.jsx("b",{style:{color:"var(--text-body)"},children:i.reporterEmail})]}),e.jsxs("span",{children:["project: ",e.jsx("b",{style:{color:"var(--text-body)"},children:i.projectId})]}),e.jsxs("span",{children:["masuk: ",Q(i.createdAt)," lalu"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Detail keluhan"}),e.jsx("div",{style:{whiteSpace:"pre-wrap",color:"var(--text-body)",fontSize:"var(--text-sm)",lineHeight:1.55},children:i.detail})]}),i.attachments.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Lampiran"}),e.jsx("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:i.attachments.map(t=>e.jsx("a",{href:q.ticketAttachment(i.id,t.id),target:"_blank",rel:"noreferrer",style:{display:"block",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden"},children:e.jsx("img",{src:q.ticketAttachment(i.id,t.id),alt:t.filename,style:{display:"block",maxWidth:180,maxHeight:140,objectFit:"cover"}})},t.id))})]}),e.jsx(ce,{open:f,title:"Hapus tiket?",eyebrow:`#${i.number}`,message:`Tiket "${i.title}" dan seluruh lampirannya akan dihapus permanen. Tindakan ini tak bisa dibatalkan.`,busy:m,onCancel:()=>B(!1),onConfirm:N}),S]})}function fe({projectId:s,onAccepted:c}){const[j,p]=l.useState([]),[n,i]=l.useState("loading"),[k,h]=l.useState(!1),[z,m]=l.useState(null),[u,g]=l.useState(null),[x,P]=l.useState([]),[b,f]=l.useState(0),[B,v]=l.useState(1),S=l.useCallback(async()=>{try{const a=await y.listGithubIssues(s,{page:B,limit:$});p(a.items),f(a.total),i("ready")}catch{i("error")}},[s,B]);l.useEffect(()=>{S()},[S]);const r=a=>{var D;const o=(D=a.detail)==null?void 0:D.error;return typeof o=="string"?o:a.message};async function I(){h(!0),g(null),m(null);try{const a=await y.pullGithubIssues(s);m(`${a.repo}: ${a.created} baru, ${a.updated} diperbarui`+(a.skippedPullRequests?` · ${a.skippedPullRequests} pull request dilewati`:"")),await S()}catch(a){g(r(a))}finally{h(!1)}}async function w(){h(!0),g(null);try{const a=await y.acceptGithubIssues(x,void 0);P([]),c==null||c(a.created),await S()}catch(a){g(r(a))}finally{h(!1)}}async function L(a){h(!0),g(null);try{await y.rejectGithubIssue(a),await S()}catch(o){g(r(o))}finally{h(!1)}}const E=a=>P(o=>o.includes(a)?o.filter(D=>D!==a):[...o,a]);return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12,minHeight:0,flex:1},children:[e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(d,{size:"sm",onClick:I,disabled:k,children:"Tarik issue"}),e.jsxs(d,{size:"sm",variant:"primary",onClick:w,disabled:k||x.length===0,children:["Terima terpilih",x.length?` (${x.length})`:""]}),z&&e.jsx("span",{style:{fontSize:12,color:"var(--text-muted)"},children:z})]}),u&&e.jsx("div",{role:"alert",style:{fontSize:12,color:"var(--danger, #b00)"},children:u}),n==="loading"?e.jsx(T,{kind:"loading"}):n==="error"?e.jsx(T,{kind:"error",hint:"Gagal memuat daftar issue.",action:()=>void S(),actionLabel:"Coba lagi"}):j.length===0?e.jsx(T,{kind:"empty",icon:"inbox",title:"Belum ada issue tertarik",hint:"Tekan “Tarik issue” untuk menariknya dari repo GitHub project ini."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{overflowY:"auto",minHeight:0},children:j.map(a=>e.jsxs("div",{className:"hn-dense-row",style:{display:"flex",gap:8,alignItems:"baseline",padding:"8px 0",borderBottom:"1px solid var(--border-hair)"},children:[a.status==="new"&&e.jsx("input",{type:"checkbox","aria-label":`Pilih issue ${a.number}`,checked:x.includes(a.id),onChange:()=>E(a.id)}),e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-muted)"},children:["#",a.number]}),e.jsx("a",{href:a.url,target:"_blank",rel:"noreferrer",style:{flex:1,minWidth:0},children:a.title}),e.jsxs("span",{style:{fontSize:12,color:"var(--text-muted)"},children:["@",a.authorLogin]}),a.labels.map(o=>e.jsx(C,{children:o},o)),a.status==="rejected"&&e.jsx(C,{tone:"neutral",children:"ditutup"}),a.specId&&e.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12},children:a.specId}),a.status==="new"&&e.jsx(d,{size:"sm",variant:"ghost",onClick:()=>L(a.id),disabled:k,children:"Tolak"})]},a.id))}),e.jsx(M,{total:b,page:B,onPage:v,unit:"issue"})]})]})}function Se({projects:s,onAccepted:c,onToast:j}){const[p,n]=l.useState([]),[i,k]=l.useState(0),[h,z]=H("triage","page",1,se),[m,u]=l.useState(0),[g,x]=l.useState("loading"),[P,b]=H("triage","openId",null,ne),[f,B]=H("triage","project","",A),[v,S]=H("triage","status","",A),[r,I]=H("triage","q","",A),[w,L]=H("triage","tab","tiket",V("tiket","issue")),E=[f!=="",v!=="",r.trim()!==""].filter(Boolean).length,a=Y("triage","scroll",p.length>0),o=l.useCallback((t=!1)=>{t||x("loading"),y.listTickets({project:f||void 0,status:v||void 0,q:r||void 0,page:String(h),limit:String($)}).then(G=>{n(G.items),k(G.total),u(G.unreviewed),x("ready")}).catch(()=>{t||x("error")})},[f,v,r,h]);l.useEffect(()=>{o()},[o]),X(JSON.stringify([f,v,r]),()=>z(1));const[D,N]=l.useState(r);l.useEffect(()=>{const t=setTimeout(()=>N(r),me);return()=>clearTimeout(t)},[r]),Z({topic:"tickets",params:{project:f||void 0,status:v||void 0,q:D||void 0,page:h,limit:$},apply:t=>{n(t.data.items),k(t.data.total),u(t.data.unreviewed),x("ready")},refetch:()=>o(!0),pollMs:he});const _=e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:12,minHeight:0,flex:1},children:f?e.jsx(fe,{projectId:f,onAccepted:t=>t.forEach(G=>c(G,!1))}):e.jsx(T,{kind:"empty",icon:"inbox",title:"Pilih satu project",hint:"Issue GitHub milik satu repo, jadi pilih project-nya lebih dulu di penyaring di atas."})}),R=e.jsx("div",{style:{display:"flex",flexDirection:"column",flex:1,minHeight:0},children:g==="loading"?e.jsx(T,{kind:"loading"}):g==="error"?e.jsx(T,{kind:"error",hint:"Gagal memuat tiket.",action:()=>o(),actionLabel:"Coba lagi"}):p.length===0?e.jsx(T,{kind:"empty",icon:"inbox",title:"Belum ada keluhan",hint:"Aktifkan Help Center di detail project, lalu sebar link publiknya agar keluhan mulai masuk."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{ref:a,"data-testid":"triage-scroll",style:{overflowY:"auto",minHeight:0,flex:"1 1 auto"},children:p.map(t=>e.jsx(ge,{t,onOpen:b},t.id))}),e.jsx(M,{total:i,page:h,onPage:z})]})});return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14,minHeight:0,flex:1},children:[e.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",gap:8,alignItems:"center"},children:[e.jsx(d,{size:"sm",variant:w==="tiket"?"primary":"ghost",onClick:()=>L("tiket"),children:"Tiket Help Center"}),e.jsx(d,{size:"sm",variant:w==="issue"?"primary":"ghost",onClick:()=>L("issue"),children:"Issue GitHub"})]}),e.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap",alignItems:"center"},children:[e.jsx(F,{size:"sm",value:f,"aria-label":"Project triase",onChange:t=>B(t.target.value),options:[{value:"",label:"Semua project"},...s.map(t=>({value:t.id,label:t.name}))]}),w==="tiket"&&e.jsxs(e.Fragment,{children:[e.jsx(F,{size:"sm",value:v,"aria-label":"Status tiket",onChange:t=>S(t.target.value),options:[{value:"",label:"Semua status"},{value:"new",label:"belum ditinjau"},{value:"accepted",label:"diterima"},{value:"rejected",label:"ditutup"}]}),e.jsx(U,{size:"sm",value:r,"aria-label":"Cari tiket",onChange:t=>I(t.target.value),placeholder:"mis. gagal login atau budi@contoh.id",style:{flex:1,minWidth:160}}),m>0&&e.jsxs(C,{tone:"warn",children:[m," belum ditinjau"]}),e.jsx(ee,{onDone:()=>o(!0),onToast:j}),e.jsx(te,{screen:"triage",active:E}),e.jsx(ue,{})]})]}),w==="issue"?_:e.jsx(ae,{ariaLabel:"Panel triase",active:P?"detail":"list",onActiveChange:t=>{t==="list"&&b(null)},splitAt:"tablet",masterWidth:360,panels:[{id:"list",label:"Daftar",content:R,className:"hn-panel-flex"},...P?[{id:"detail",label:"Detail",className:"hn-panel-flex",content:e.jsx(xe,{id:P,onBack:()=>{b(null),o(!0)},onAccepted:c,onDeleted:()=>{b(null),o(!0)},onToast:j})}]:[]]})]})}export{fe as GithubIssuesPanel,Se as TriageScreen};
@@ -1,2 +0,0 @@
1
- import{e as v,u as te,j as e,M as oe,f as U,I as W,a as f,h as de,o as fe,aE as be,at as ke,c as O,d as T,aa as ye,ao as se,y as ve}from"./index-gNO91_qw.js";import{R as p}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";const je={pass:"check",fail:"x",warn:"alert-triangle",na:"minus",unknown:"circle"},we={pass:"var(--leaf-600)",fail:"var(--clay-600)",warn:"var(--amber-600)",na:"var(--text-subtle)",unknown:"var(--text-subtle)"},Se={AUTO:"var(--brass-700)",AUDIT:"var(--amber-600)",INFO:"var(--text-subtle)"},Ce={critical:"var(--clay-600)",high:"var(--amber-600)",medium:"var(--text-subtle)",low:"var(--text-subtle)"};function K({text:a,color:s}){return e.jsx("span",{style:{fontSize:10,textTransform:"uppercase",letterSpacing:"0.04em",color:s,border:`1px solid ${s}`,borderRadius:3,padding:"0 4px",whiteSpace:"nowrap"},children:a})}function ce({score:a}){const s=a>=90?"var(--leaf-600)":a>=50?"var(--amber-600)":"var(--clay-600)";return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,minWidth:90},children:[e.jsx("div",{style:{flex:1,height:6,background:"var(--bone-200)",borderRadius:3,overflow:"hidden"},children:e.jsx("div",{style:{width:`${a}%`,height:"100%",background:s}})}),e.jsxs("span",{style:{fontSize:11,fontFamily:"var(--font-mono)",color:"var(--text-subtle)",minWidth:28,textAlign:"right"},children:[a,"%"]})]})}function Pe({item:a,busy:s,selected:l,onToggle:o,onNa:u,onAttest:c}){const n=a.mode==="AUTO"&&!a.na;return e.jsxs("div",{"data-testid":`item-${a.id}`,style:{display:"flex",alignItems:"center",gap:8,padding:"5px 0",borderBottom:"1px solid var(--border-hair)",fontSize:13,opacity:a.na?.55:1},children:[n?e.jsx("input",{type:"checkbox","aria-label":`pilih ${a.id}`,checked:l,onChange:()=>o(a)}):e.jsx("span",{style:{display:"inline-block",width:13}}),e.jsx(W,{name:je[a.status],size:14,color:we[a.status]}),e.jsx("span",{style:{flex:1,minWidth:0},children:a.title}),a.drifted&&e.jsx(K,{text:"drift",color:"var(--clay-600)"}),e.jsx(K,{text:a.mode,color:Se[a.mode]}),e.jsx(K,{text:a.severity,color:Ce[a.severity]}),a.mode==="INFO"&&!a.attested&&e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"check-circle",loading:s,onClick:()=>c(a),children:"Attest"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:a.na?"rotate-ccw":"minus-circle",loading:s,onClick:()=>u(a,!a.na),children:a.na?"Batal N/A":"N/A"})]})}const ee={section:"",mode:"",status:"",severity:""};function J({value:a,onChange:s,options:l,label:o}){return e.jsxs("select",{"aria-label":o,value:a,onChange:u=>s(u.target.value),style:{fontSize:12,padding:"3px 6px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",background:"var(--bone-50)",color:"var(--text)"},children:[e.jsxs("option",{value:"",children:[o,": semua"]}),l.map(([u,c])=>e.jsx("option",{value:u,children:c},u))]})}function ze(a){let s=0,l=0,o=0,u=0;for(const n of a)n.status==="fail"?s++:n.status==="warn"?l++:n.status==="unknown"&&o++,n.drifted&&u++;const c=[s&&`${s} fail`,l&&`${l} warn`,o&&`${o} unknown`].filter(Boolean);return{text:c.length?c.join(" "):"semua pass",drift:u}}function $e({section:a,items:s,expanded:l,onToggle:o,busy:u,selected:c,onToggleItem:n,onNa:b,onAttest:g,onSectionNa:k}){const S=ze(a.items),h=!!a.suggestion&&!a.suggestion.applicable;return e.jsxs("div",{style:{marginBottom:8,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden"},children:[e.jsxs("button",{"data-testid":`section-${a.id}`,"aria-expanded":l,onClick:()=>o(a.id),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"8px 10px",textAlign:"left",background:l?"var(--bone-100)":"transparent",border:"none",cursor:"pointer"},children:[e.jsx(W,{name:l?"chevron-down":"chevron-right",size:15,color:"var(--text-subtle)"}),e.jsx("span",{style:{fontSize:14},children:a.icon}),e.jsx("span",{style:{fontSize:13,fontWeight:600,flex:1,minWidth:0},children:a.title}),e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)",whiteSpace:"nowrap"},children:S.text}),S.drift>0&&e.jsx(K,{text:"drift",color:"var(--clay-600)"}),h&&e.jsx(K,{text:"saran N/A",color:"var(--brass-700)"}),e.jsx(ce,{score:a.score})]}),l&&e.jsxs("div",{style:{padding:"2px 10px 8px"},children:[h&&e.jsxs("div",{"data-testid":`suggestion-${a.id}`,style:{display:"flex",alignItems:"center",gap:8,margin:"6px 0",padding:"6px 10px",fontSize:12,color:"var(--text-subtle)",background:"var(--bone-50)",border:"1px dashed var(--border-hair)",borderRadius:"var(--radius-sm)"},children:[e.jsx(W,{name:"info",size:13,color:"var(--brass-700)"}),e.jsxs("span",{style:{flex:1},children:["Stack tak terdeteksi (",a.suggestion.detail,") — kemungkinan N/A. Cek Docker manual bila ragu."]}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"minus-circle",loading:u===`section:${a.id}`,onClick:()=>k(a),children:"Tandai seksi N/A"})]}),s.map(y=>e.jsx(Pe,{item:y,busy:u===y.id,selected:c.has(y.id),onToggle:n,onNa:b,onAttest:g},y.id))]})]})}function Ae({vpsId:a,vpsName:s,lastAuditAt:l,health:o,provisioning:u,onClose:c,onToast:n}){const[b,g]=p.useState(null),[k,S]=p.useState("loading"),[h,y]=p.useState(ee),[P,w]=p.useState(""),[B,E]=p.useState(new Set),[$,C]=p.useState(null),[R,V]=p.useState(new Set),[F,D]=p.useState(null),[A,L]=p.useState(""),I=p.useCallback(()=>{S("loading"),v.vpsChecklist(a).then(r=>{g(r),S("ready")}).catch(()=>S("error"))},[a]);p.useEffect(()=>{I(),V(new Set),D(null),E(new Set),w(""),y(ee)},[I]);const t=r=>V(j=>{const d=new Set(j);return d.has(r.id)?d.delete(r.id):d.add(r.id),d}),x=()=>{V(new Set),D(null)},m=r=>E(j=>{const d=new Set(j);return d.has(r)?d.delete(r):d.add(r),d}),{confirm:H,dialog:X}=te();async function M(){L("preview");try{D((await v.remediatePreview(a,[...R])).steps)}catch{n("Preview remediasi gagal","err","x-circle")}finally{L("")}}async function Y(){if(await H({title:`Terapkan ${R.size} item AUTO ke VPS ini?`,message:"Remediasi dijalankan langsung di server yang terdaftar.",impact:["Langkahnya idempoten dan anti-lockout.","Checklist diaudit ulang setelah selesai."],confirmLabel:"Terapkan",icon:"shield"})){L("apply");try{await v.remediate(a,[...R]),x(),I(),n("Remediasi diterapkan · audit ulang","ok","shield")}catch{n("Remediasi gagal","err","x-circle")}finally{L("")}}}async function _(r,j,d){C(r.id);try{await j(),I(),n(d,"ok","shield")}catch{n(`Gagal memperbarui ${r.id}`,"err","x-circle")}finally{C(null)}}const i=(r,j)=>_(r,()=>v.markNa(a,r.id,j,j?"ditandai dari checklist":void 0),j?`${r.id} ditandai N/A`:`${r.id} kembali applicable`),z=r=>_(r,()=>v.attestItem(a,r.id),`${r.id} di-attest`);async function N(r){const j=r.items.map(d=>d.id);if(await H({title:`Tandai ${j.length} item seksi "${r.title}" sebagai N/A?`,message:"Stack-nya tak terdeteksi — cek Docker manual bila ragu.",confirmLabel:"Tandai N/A",icon:"shield"})){C(`section:${r.id}`);try{await v.markNaBulk(a,j,!0,"app-layer: stack tak terdeteksi"),I(),n(`Seksi ${r.title} ditandai N/A`,"ok","shield")}catch{n("Gagal tandai seksi N/A","err","x-circle")}finally{C(null)}}}const G=P.trim().toLowerCase(),q=!!(h.section||h.mode||h.status||h.severity)||G!=="",me=r=>(!h.section||r.section===h.section)&&(!h.mode||r.mode===h.mode)&&(!h.status||r.status===h.status)&&(!h.severity||r.severity===h.severity)&&(!G||r.title.toLowerCase().includes(G)||r.id.toLowerCase().includes(G)||(r.code??"").toLowerCase().includes(G)),Q=r=>j=>y(d=>({...d,[r]:j}));function ge(){if(k==="loading")return e.jsx(U,{kind:"loading",compact:!0,title:"Memuat checklist…"});if(k==="error"||!b)return e.jsx(U,{kind:"error",compact:!0,title:"Gagal memuat checklist",action:I});const r=b.sections.reduce((d,Z)=>d+Z.items.filter(xe=>xe.drifted).length,0),j=b.sections.map(d=>({section:d,matched:d.items.filter(me)})).filter(d=>!q||d.matched.length>0);return e.jsxs("div",{children:[e.jsxs("div",{style:{position:"sticky",top:0,zIndex:1,background:"var(--surface-card)",paddingBottom:10},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:10},children:[e.jsxs("div",{"data-testid":"score-total",style:{fontSize:22,fontWeight:700,fontFamily:"var(--font-mono)"},children:[b.scoreTotal,"%"]}),e.jsx("div",{style:{flex:1},children:e.jsx(ce,{score:b.scoreTotal})}),e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"skor kepatuhan"})]}),r>0&&e.jsxs("div",{"data-testid":"drift-summary",style:{display:"flex",alignItems:"center",gap:6,marginBottom:10,padding:"6px 10px",fontSize:12,color:"var(--clay-700)",background:"var(--clay-50, var(--bone-100))",border:"1px solid var(--clay-600)",borderRadius:"var(--radius-sm)"},children:[e.jsx(W,{name:"alert-triangle",size:14,color:"var(--clay-600)"}),r," item drift (regresi) sejak audit sebelumnya"]}),e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:6,alignItems:"center"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,flex:"1 1 180px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",padding:"2px 8px",background:"var(--bone-50)"},children:[e.jsx(W,{name:"search",size:13,color:"var(--text-subtle)"}),e.jsx("input",{"aria-label":"cari item",value:P,onChange:d=>w(d.target.value),placeholder:"mis. ssh atau 5.2.1",style:{flex:1,border:"none",background:"transparent",fontSize:12,color:"var(--text)",outline:"none"}})]}),e.jsx(J,{label:"seksi",value:h.section,onChange:Q("section"),options:b.sections.map(d=>[d.id,d.title])}),e.jsx(J,{label:"mode",value:h.mode,onChange:Q("mode"),options:[["AUTO","AUTO"],["AUDIT","AUDIT"],["INFO","INFO"]]}),e.jsx(J,{label:"status",value:h.status,onChange:Q("status"),options:[["pass","pass"],["fail","fail"],["warn","warn"],["na","na"],["unknown","unknown"]]}),e.jsx(J,{label:"severity",value:h.severity,onChange:Q("severity"),options:[["critical","critical"],["high","high"],["medium","medium"],["low","low"]]}),q&&e.jsx(f,{size:"sm",variant:"ghost",onClick:()=>{y(ee),w("")},children:"Reset"})]}),R.size>0&&e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginTop:10,padding:"8px 10px",background:"var(--bone-100)",border:"1px solid var(--brass-300)",borderRadius:"var(--radius-sm)"},children:[e.jsxs("span",{style:{fontSize:12,flex:1},children:[R.size," item AUTO dipilih"]}),e.jsx(f,{size:"sm",variant:"secondary",leftIcon:"eye",loading:A==="preview",onClick:M,children:"Preview"}),e.jsx(f,{size:"sm",leftIcon:"shield",loading:A==="apply",onClick:Y,children:"Apply"}),e.jsx(f,{size:"sm",variant:"ghost",onClick:x,children:"Batal"})]}),F&&e.jsxs("div",{"data-testid":"remediate-preview",style:{marginTop:10,padding:"8px 10px",fontSize:12,fontFamily:"var(--font-mono)",background:"var(--bone-50)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)"},children:[e.jsx("div",{style:{fontWeight:600,marginBottom:4},children:"Pratinjau (dry-run) — belum diterapkan:"}),F.map(d=>e.jsxs("div",{style:{color:"var(--text-subtle)"},children:[d.item," · ",d.status," ",d.detail]},d.item))]})]}),j.length===0?e.jsx(U,{kind:"empty",compact:!0,title:"Tak ada item cocok",hint:"Ubah kata kunci atau reset filter."}):j.map(({section:d,matched:Z})=>e.jsx($e,{section:d,items:q?Z:d.items,expanded:q?!0:B.has(d.id),onToggle:m,busy:$,selected:R,onToggleItem:t,onNa:i,onAttest:z,onSectionNa:N},d.id))]})}return e.jsxs(oe,{open:!0,width:960,icon:"clipboard-list",eyebrow:s??"VPS",title:"Checklist kepatuhan",onClose:c,children:[e.jsxs("div",{"data-testid":"vps-detail",style:{fontSize:12,color:"var(--text-subtle)",marginBottom:12,paddingBottom:10,borderBottom:"1px solid var(--border-hair)"},children:[l?`Audit terakhir ${new Date(l).toLocaleString()}`:"Belum pernah diaudit",o&&` · disk ${o.disk} · mem ${o.mem} · load ${o.load}`]}),u&&e.jsx("div",{"data-testid":"vps-provisioning",style:{marginBottom:12,paddingBottom:10,borderBottom:"1px solid var(--border-hair)"},children:u}),ge(),X]})}const ne={ok:"terpasang",partial:"belum siap",absent:"belum ada"},ue={ok:"var(--leaf-600)",partial:"var(--amber-600)",absent:"var(--text-subtle)"};function pe(a,s){if(s.status==="partial"&&s.detail.startsWith("not-logged-in"))return`${a} · belum login`;if(s.status==="partial")return`${a} · ${s.detail||ne.partial}`;const l=s.status==="ok"&&s.detail?` ${s.detail}`:"";return`${a} · ${ne[s.status]??s.status}${l}`}const Ie={ok:"terpasang",partial:"belum siap",absent:"belum ada"};function he({status:a,children:s,title:l}){const o=ue[a]??"var(--text-subtle)";return e.jsxs("span",{title:l,style:{display:"inline-flex",alignItems:"center",gap:5,fontSize:11,lineHeight:"18px",color:"var(--text-primary)",background:"var(--surface-sunken)",border:"1px solid var(--border-hair)",borderRadius:999,padding:"0 8px",whiteSpace:"nowrap"},children:[e.jsx("span",{"aria-hidden":!0,style:{width:6,height:6,borderRadius:"50%",background:o,flex:"0 0 auto"}}),s]})}function Be({components:a,checkedAt:s}){return!a||!s?e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"Komponen belum diperiksa"}):e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:6,alignItems:"center"},children:[Object.entries(a).map(([l,o])=>e.jsx(he,{status:o.status,children:pe(l,o)},l)),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:["diperiksa ",new Date(s).toLocaleString("id-ID")]})]})}const Re=a=>new Date(a).toLocaleString("id-ID",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"});function Le({components:a,checkedAt:s}){if(!a||!s)return e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"Komponen belum diperiksa — buka detail untuk memeriksa"});const l=Object.entries(a),o=l.filter(([,c])=>c.status!=="ok"),u=l.length-o.length;return e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:8,alignItems:"center",minWidth:0},children:[e.jsx("span",{"aria-hidden":!0,style:{display:"flex",gap:2,alignItems:"center"},children:l.map(([c,n])=>e.jsx("span",{style:{width:12,height:4,borderRadius:2,background:n.status==="absent"?"var(--border-strong)":ue[n.status]}},c))}),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)",whiteSpace:"nowrap"},children:[e.jsxs("strong",{style:{color:"var(--text-primary)",fontWeight:600},children:[u,"/",l.length]})," terpasang"]}),o.map(([c,n])=>e.jsxs(he,{status:n.status,title:pe(c,n),children:[c," · ",n.status==="partial"&&n.detail.startsWith("not-logged-in")?"belum login":Ie[n.status]??n.status]},c)),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)",whiteSpace:"nowrap"},children:["diperiksa ",Re(s)]})]})}function Ne(a,s,l){const o=new Map(s.map(n=>[n.id,n])),u=new Set,c=n=>{var b;if(!u.has(n)){u.add(n);for(const g of((b=o.get(n))==null?void 0:b.requires[l])??[])c(g)}};for(const n of a)c(n);return u}function De({vps:a,onToast:s,onGotoTerminal:l}){const[o,u]=p.useState([]),[c,n]=de("vps",`provisionProfile@${a.id}`,"lab",fe("lab","production")),[b,g]=p.useState(new Set),[k,S]=p.useState(""),[h,y]=p.useState(null),[P,w]=p.useState(null),[B,E]=p.useState(null),[$,C]=p.useState(null),{confirm:R,dialog:V}=te();p.useEffect(()=>{v.listVpsComponents().then(i=>u(i.components)).catch(()=>u([]))},[]);const F=o.filter(i=>i.profiles.includes(c)),D=Ne(b,o,c),A=[...D],L=A.some(i=>{var z;return(z=o.find(N=>N.id===i))==null?void 0:z.needsDomain}),I=A.length>0&&(!L||k.trim().length>0);function t(i){g(z=>{const N=new Set(z);return N.has(i)?N.delete(i):N.add(i),N})}async function x(){C("probe");try{w(await v.probeVps(a.id)),s("Komponen diperiksa","ok","server")}catch{s("Probe gagal","err","x-circle")}finally{C(null)}}async function m(){C("preview");try{y((await v.provisionPreview(a.id,{items:A,profile:c,domain:k||void 0})).steps)}catch{s("Pratinjau gagal","err","x-circle")}finally{C(null)}}async function H(){if(await R({title:`Pasang ${A.length} komponen di "${a.name}"?`,message:`Profil ${c}. Langkah dijalankan lewat SSH dan bisa memakan beberapa menit.`,impact:A.map(i=>{var z;return((z=o.find(N=>N.id===i))==null?void 0:z.label)??i}),confirmLabel:"Pasang",icon:"server"})){C("apply");try{const i=await v.provisionVps(a.id,{items:A,profile:c,domain:k||void 0,confirm:!0});y(i.steps),w({components:i.components,checkedAt:i.checkedAt}),E(i.setup),s("Provisioning selesai","ok","server")}catch{s("Provisioning gagal","err","x-circle")}finally{C(null)}}}const X=async()=>{try{const{id:i}=await v.vpsConsole(a.id);l(i)}catch{s("Gagal membuka console","err","x-circle")}},M=P?Object.fromEntries(P.components.map(i=>[i.id,{status:i.status,detail:i.detail}])):a.components??null,Y=(P==null?void 0:P.checkedAt)??a.componentsCheckedAt??null,_=M?Object.entries(M).filter(([,i])=>i.status==="partial"&&i.detail.startsWith("not-logged-in")):[];return e.jsxs("div",{style:{display:"grid",gap:12},children:[e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(Be,{components:M,checkedAt:Y}),e.jsx(f,{size:"sm",variant:"ghost",onClick:x,disabled:$!==null,children:"Periksa"})]}),e.jsx("div",{style:{display:"flex",gap:16},children:["lab","production"].map(i=>e.jsx(be,{"aria-label":i,label:i,checked:c===i,onChange:()=>n(i)},i))}),e.jsx("div",{style:{display:"grid",gap:6},children:F.map(i=>{const z=D.has(i.id)&&!b.has(i.id);return e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[e.jsx(ke,{"aria-label":i.label,label:i.label,checked:D.has(i.id),disabled:z,onChange:()=>t(i.id)}),z&&e.jsx("span",{style:{fontSize:10,color:"var(--text-subtle)"},children:"prasyarat"})]},i.id)})}),L&&e.jsx(O,{label:"Domain",hint:"A record harus sudah menunjuk ke IP VPS ini",children:e.jsx(T,{"aria-label":"Domain",value:k,onChange:i=>S(i.currentTarget.value),placeholder:"hanoman.contoh.id"})}),e.jsxs("div",{style:{display:"flex",gap:8},children:[e.jsx(f,{variant:"ghost",onClick:m,disabled:!I||$!==null,children:"Pratinjau"}),e.jsx(f,{onClick:H,disabled:!I||$!==null,children:"Pasang"})]}),h&&e.jsx("pre",{style:{fontSize:11,fontFamily:"var(--font-mono)",maxHeight:220,overflow:"auto",background:"var(--surface-sunken)",padding:8,borderRadius:4},children:h.map(i=>`${i.item.padEnd(14)} ${i.status.padEnd(6)} ${i.detail}`).join(`
2
- `)}),B&&e.jsxs("div",{style:{display:"grid",gap:4,border:"1px solid var(--border-strong)",borderRadius:4,padding:8},children:[e.jsx("strong",{style:{fontSize:12},children:"Buat admin pertama"}),e.jsx("a",{href:B.url,target:"_blank",rel:"noreferrer",style:{fontSize:12,wordBreak:"break-all"},children:B.url}),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:["berlaku sampai ",new Date(B.expiresAt).toLocaleTimeString("id-ID")]}),e.jsx("div",{children:e.jsx(f,{size:"sm",variant:"ghost",onClick:()=>{var i;return void((i=navigator.clipboard)==null?void 0:i.writeText(B.url))},children:"Salin"})})]}),_.length>0&&e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",fontSize:12},children:[e.jsx(W,{name:"alert-triangle"}),e.jsxs("span",{children:[_.map(([i])=>i).join(", ")," terpasang tapi belum login."]}),e.jsx(f,{size:"sm",variant:"ghost",onClick:X,children:"Login lewat Console"})]}),V]})}const ie=(a,s=Date.now())=>!!a.lastSeenAt&&s-new Date(a.lastSeenAt).getTime()<10*6e4,Ve=a=>a.lastAuditAt?a.hardened?"hardened":"belum":"unknown",Oe={hardened:{status:"ok",label:"hardened"},belum:{status:"broken",label:"belum hardened"},unknown:{status:"idle",label:"belum diaudit"}};function re(a){const s={name:a.name.trim(),host:a.host.trim(),user:a.user.trim(),port:Number(a.port)||22};return a.keyPath.trim()&&(s.keyPath=a.keyPath.trim()),a.password&&(s.password=a.password),s}const Te="opsional — dipakai sekali untuk memasang key hanoman, tidak disimpan";function ae({open:a,title:s,submitLabel:l,initial:o,onClose:u,onSubmit:c}){const[n,b]=p.useState(o);p.useEffect(()=>{a&&b(o)},[a,o]);const g=S=>h=>b(y=>({...y,[S]:h.target.value})),k=!!(n.name.trim()&&n.host.trim()&&n.user.trim());return e.jsxs(oe,{open:a,onClose:u,icon:"server",eyebrow:"infra",title:s,footer:e.jsxs(e.Fragment,{children:[e.jsx(f,{variant:"ghost",size:"sm",onClick:u,children:"Batal"}),e.jsx(f,{size:"sm",leftIcon:"check",onClick:()=>k&&c(n),children:l})]}),children:[e.jsx(O,{label:"Nama",children:e.jsx(T,{value:n.name,onChange:g("name"),placeholder:"mis. web-1",style:{width:"100%"}})}),e.jsx(O,{label:"Host",hint:"hostname atau IP — tanpa user@",children:e.jsx(T,{value:n.host,onChange:g("host"),mono:!0,placeholder:"203.0.113.10",style:{width:"100%"}})}),e.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"1.4fr 1fr",gap:12},children:[e.jsx(O,{label:"User SSH",hint:"root atau user ber-passwordless-sudo",children:e.jsx(T,{value:n.user,onChange:g("user"),mono:!0,placeholder:"deploy",style:{width:"100%"}})}),e.jsx(O,{label:"Port",children:e.jsx(T,{value:n.port,onChange:g("port"),mono:!0,placeholder:"22",style:{width:"100%"}})})]}),e.jsx(O,{label:"Password SSH",hint:Te,children:e.jsx(T,{type:"password",value:n.password,onChange:g("password"),placeholder:"••••••••",style:{width:"100%"}})}),e.jsx(O,{label:"Key path",hint:"kosongkan bila memakai password di atas, atau key default mesin server",children:e.jsx(T,{value:n.keyPath,onChange:g("keyPath"),mono:!0,placeholder:"~/.ssh/id_ed25519",style:{width:"100%"}})})]})}const le={name:"",host:"",user:"",port:"22",keyPath:"",password:""},We=a=>({name:a.name,host:a.host,user:a.user,port:String(a.port),keyPath:a.keyPath??"",password:""});function _e({onToast:a,onGotoTerminal:s}){const[l,o]=p.useState([]),[u,c]=p.useState("loading"),[n,b]=p.useState(null),[g,k]=p.useState(null),[S,h]=de("vps","detailId",null,ve),y=p.useMemo(()=>l.find(t=>t.id===S)??null,[l,S]),P=p.useCallback(t=>h(t?t.id:null),[h]),w=p.useCallback(()=>{v.listVps().then(t=>{o(t),c("ready")}).catch(()=>c("error"))},[]);p.useEffect(()=>(w(),ye(t=>{t.t==="vps"&&(o(t.vps),c("ready"))})),[w]);const{confirm:B,dialog:E}=te();async function $(t,x,m,H){b(`${t}:${x}`);try{await m(),w(),a(H,"ok","server")}catch{a(`Gagal ${t}`,"err","x-circle")}finally{b(null)}}const C=t=>$("audit",t.id,()=>v.auditVps(t.id),`${t.name} · audit selesai`);async function R(t){await B({title:`Harden "${t.name}"?`,message:"Pastikan akses key SSH non-password kamu sudah bekerja sebelum melanjutkan.",impact:[`Firewall: izinkan ${t.port}/80/443.`,"fail2ban & auto security update dipasang.","PermitRootLogin & PasswordAuthentication dimatikan.","NTP disinkronkan."],confirmLabel:"Harden",icon:"shield"})&&$("harden",t.id,()=>v.hardenVps(t.id),`${t.name} · harden selesai`)}const V=t=>$("sesi",t.id,async()=>{const{id:x}=await v.vpsSession(t.id);s(x)},`${t.name} · sesi Claude dibuka`),F=t=>$("test",t.id,async()=>{const x=await v.testVps(t.id);if(!x.ok)throw new Error(x.out)},`${t.name} · koneksi ok`),D=t=>$("console",t.id,async()=>{const{id:x}=await v.vpsConsole(t.id);s(x)},`${t.name} · console dibuka`);async function A(t){try{if(!await B({title:`Hapus registrasi VPS "${t.name}"?`,message:"Server-nya sendiri tak disentuh — hanya pendaftarannya di dashboard ini yang dihapus.",confirmLabel:"Hapus registrasi",run:()=>v.deleteVps(t.id)}))return;w()}catch{a("Gagal hapus","err","x-circle")}}async function L(t){try{const x=await v.createVps(re(t));k(null),w(),a(t.password?`${x.name} terdaftar · key hanoman terpasang · password dibuang`:`${x.name} terdaftar · jalankan audit`,"ok","server")}catch{a("Gagal mendaftarkan VPS — cek host/user, atau password SSH-nya","err","x-circle")}}async function I(t,x){try{const m=await v.updateVps(t.id,re(x));k(null),w(),a(x.password?`${m.name} diperbarui · key hanoman terpasang · password dibuang`:`${m.name} diperbarui`,"ok","server")}catch{a("Gagal memperbarui VPS","err","x-circle")}}return u==="loading"?e.jsx(U,{kind:"loading",title:"Memuat daftar VPS…"}):u==="error"?e.jsx(U,{kind:"error",title:"Gagal memuat daftar VPS",hint:"Pastikan server hanoman berjalan.",action:w}):l.length===0?e.jsxs(e.Fragment,{children:[e.jsx(U,{kind:"empty",icon:"server",title:"Belum ada VPS",hint:"Daftarkan VPS untuk mulai audit & hardening.",action:()=>k("new"),actionLabel:"Daftarkan VPS"}),e.jsx(ae,{open:g==="new",title:"Daftarkan VPS",submitLabel:"Daftarkan",initial:le,onClose:()=>k(null),onSubmit:L})]}):e.jsxs("div",{children:[e.jsxs("div",{children:[e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginBottom:10},children:e.jsx(f,{size:"sm",leftIcon:"plus",onClick:()=>k("new"),children:"Daftarkan VPS"})}),l.map(t=>{const x=Oe[Ve(t)];return e.jsxs("div",{className:"hn-vps-row",onClick:()=>P(t),style:{padding:"10px 12px",cursor:"pointer",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",marginBottom:8},children:[e.jsxs("div",{className:"hn-vps-main",children:[e.jsxs("button",{type:"button","aria-label":`Buka detail ${t.name}`,onClick:m=>{m.stopPropagation(),P(t)},style:{display:"flex",alignItems:"center",gap:10,flex:"1 1 220px",minWidth:0,cursor:"pointer",font:"inherit",color:"inherit",textAlign:"left",background:"transparent",padding:0,border:"none"},children:[e.jsx(W,{name:"server",size:16,color:"var(--brass-700)"}),e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block",fontSize:13,fontWeight:600,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:t.name}),e.jsxs("span",{style:{display:"block",fontSize:12,fontFamily:"var(--font-mono)",color:"var(--text-subtle)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:[t.user,"@",t.host,t.port!==22?`:${t.port}`:""]})]})]}),e.jsxs("div",{className:"hn-vps-pills",style:{display:"flex",gap:6,alignItems:"center",flexShrink:0},children:[e.jsx(se,{size:"sm",status:ie(t)?"ok":"broken",children:ie(t)?"reachable":"unreachable"}),e.jsx(se,{size:"sm",status:x.status,children:x.label})]}),e.jsxs("div",{className:"hn-vps-actions",children:[e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"plug-zap",loading:n===`test:${t.id}`,onClick:m=>{m.stopPropagation(),F(t)},children:"Test"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"terminal-square",loading:n===`console:${t.id}`,onClick:m=>{m.stopPropagation(),D(t)},children:"Console"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"terminal",loading:n===`sesi:${t.id}`,onClick:m=>{m.stopPropagation(),V(t)},children:"Sesi Claude"}),e.jsx(f,{size:"sm",variant:"secondary",leftIcon:"radar",loading:n===`audit:${t.id}`,onClick:m=>{m.stopPropagation(),C(t)},children:"Audit"}),e.jsx(f,{size:"sm",leftIcon:"shield",loading:n===`harden:${t.id}`,onClick:m=>{m.stopPropagation(),R(t)},children:"Harden"}),e.jsx("span",{"aria-hidden":!0,className:"hn-vps-sep"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"pencil",title:`Edit ${t.name}`,onClick:m=>{m.stopPropagation(),k(t)}}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"trash-2",title:`Hapus ${t.name}`,onClick:m=>{m.stopPropagation(),A(t)}})]})]}),e.jsx("div",{style:{marginTop:8,paddingTop:8,borderTop:"1px solid var(--border-hair)"},children:e.jsx(Le,{components:t.components??null,checkedAt:t.componentsCheckedAt??null})})]},t.id)})]}),y&&e.jsx(Ae,{vpsId:y.id,vpsName:y.name,lastAuditAt:y.lastAuditAt,health:y.health,provisioning:e.jsx(De,{vps:y,onToast:a,onGotoTerminal:s}),onClose:()=>{P(null),w()},onToast:a}),e.jsx(ae,{open:g==="new",title:"Daftarkan VPS",submitLabel:"Daftarkan",initial:le,onClose:()=>k(null),onSubmit:L}),g&&g!=="new"&&e.jsx(ae,{open:!0,title:`Edit ${g.name}`,submitLabel:"Simpan",initial:We(g),onClose:()=>k(null),onSubmit:t=>I(g,t)}),E]})}export{_e as VpsScreen,Ve as hardenedLabel,ie as isReachable,re as vpsFormToBody};
@@ -1,32 +0,0 @@
1
- @import"https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Serif:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,600;1,400&display=swap";:root{--ink-900: #17130c;--ink-800: #241d13;--ink-700: #3a3125;--ink-600: #574b3a;--ink-500: #6f6250;--ink-400: #90826c;--ink-300: #b3a794;--ink-200: #d6ccb9;--bone-000: #fffdf8;--bone-100: #faf6ec;--bone-200: #f2ebdc;--bone-300: #e8dfcc;--bone-400: #dccfb6;--brass-700: #7a5417;--brass-600: #97671f;--brass-500: #b8863b;--brass-400: #cf9d55;--brass-300: #e3c988;--brass-100: #f3e6c4;--brass-050: #faf2df;--wind-700: #2f5560;--wind-600: #3f6e7a;--wind-500: #517f8c;--wind-100: #dbe7ea;--wind-050: #eef4f5;--leaf-600: #4d6b30;--leaf-500: #5f8340;--leaf-100: #e6eed7;--amber-600: #b3771a;--amber-500: #cf8f28;--amber-100: #f7e9c9;--clay-600: #a23b2e;--clay-500: #bd4a3a;--clay-100: #f5dcd6;--term-bg: #1c1810;--term-fg: #e9e0cd;--term-dim: #8f8467;--term-line: #2c2618;--surface-page: var(--bone-100);--surface-panel: var(--bone-200);--surface-card: var(--bone-000);--surface-sunken: var(--bone-200);--surface-inverse: var(--ink-900);--surface-code: var(--term-bg);--text-strong: var(--ink-900);--text-body: var(--ink-700);--text-muted: var(--ink-500);--text-subtle: var(--ink-400);--text-on-brass: var(--ink-900);--text-on-dark: var(--term-fg);--text-link: var(--wind-600);--border-hair: var(--bone-300);--border-strong: var(--bone-400);--border-focus: var(--brass-500);--accent: var(--brass-500);--accent-hover: var(--brass-600);--accent-press: var(--brass-700);--accent-tint: var(--brass-100);--accent-on: var(--ink-900);--info: var(--wind-600);--info-tint: var(--wind-100);--status-ok: var(--leaf-600);--status-ok-tint: var(--leaf-100);--status-warn: var(--amber-600);--status-warn-tint: var(--amber-100);--status-err: var(--clay-600);--status-err-tint: var(--clay-100);--ring: 0 0 0 3px color-mix(in srgb, var(--brass-500) 45%, transparent)}:root{--font-serif: "IBM Plex Serif", Georgia, "Times New Roman", serif;--font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;--font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;--font-display: var(--font-serif);--font-body: var(--font-sans);--font-ui: var(--font-sans);--font-code: var(--font-mono);--text-2xs: 11px;--text-xs: 12px;--text-sm: 13px;--text-md: 14px;--text-base:16px;--text-lg: 18px;--text-xl: 20px;--text-2xl: 24px;--text-3xl: 30px;--text-4xl: 38px;--text-5xl: 48px;--text-6xl: 62px;--weight-regular: 400;--weight-medium: 500;--weight-semibold: 600;--weight-bold: 700;--leading-tight: 1.12;--leading-snug: 1.3;--leading-normal: 1.5;--leading-relaxed:1.65;--tracking-tight: -.02em;--tracking-normal: 0;--tracking-wide: .02em;--tracking-caps: .14em}:root{--space-0: 0;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--space-7: 32px;--space-8: 40px;--space-9: 48px;--space-10: 64px;--space-11: 80px;--space-12: 96px;--radius-xs: 3px;--radius-sm: 5px;--radius-md: 8px;--radius-lg: 12px;--radius-xl: 16px;--radius-pill: 999px;--border-thin: 1px;--border-med: 1.5px;--border-thick:2px;--content-max: 1200px;--sidebar-w: 248px;--topbar-h: 56px;--page-gutter-x: 28px;--page-gutter-y: 24px;--touch-target: 44px;--safe-top: env(safe-area-inset-top, 0px);--safe-right: env(safe-area-inset-right, 0px);--safe-bottom: env(safe-area-inset-bottom, 0px);--safe-left: env(safe-area-inset-left, 0px)}@media (min-width: 768px) and (max-width: 1199px){:root{--sidebar-w: 72px;--page-gutter-x: 20px;--page-gutter-y: 20px}}@media (max-width: 767px){:root{--sidebar-w: 0px;--page-gutter-x: 14px;--page-gutter-y: 14px}}:root{--shadow-xs: 0 1px 1px rgba(35, 27, 15, .05);--shadow-sm: 0 1px 2px rgba(35, 27, 15, .06), 0 1px 1px rgba(35, 27, 15, .04);--shadow-md: 0 2px 4px rgba(35, 27, 15, .07), 0 4px 12px rgba(35, 27, 15, .06);--shadow-lg: 0 8px 24px rgba(35, 27, 15, .1), 0 2px 6px rgba(35, 27, 15, .06);--shadow-xl: 0 20px 48px rgba(35, 27, 15, .16), 0 4px 12px rgba(35, 27, 15, .08);--shadow-inset: inset 0 1px 2px rgba(35, 27, 15, .08);--shadow-gild: 0 1px 0 rgba(255, 253, 248, .6) inset, 0 0 0 1px var(--brass-300);--elevation-flat: none;--elevation-raised: var(--shadow-sm);--elevation-float: var(--shadow-md);--elevation-overlay:var(--shadow-lg);--elevation-modal: var(--shadow-xl);--ease-out: cubic-bezier(.22, .61, .36, 1);--ease-inout: cubic-bezier(.65, 0, .35, 1);--ease-fall: cubic-bezier(.55, .085, .68, .53);--dur-fast: .12s;--dur-base: .18s;--dur-slow: .28s;--transition-base: all var(--dur-base) var(--ease-out);--transition-fast: all var(--dur-fast) var(--ease-out)}*,*:before,*:after{box-sizing:border-box}body{margin:0;background:var(--surface-page);color:var(--text-body);font-family:var(--font-body);font-size:var(--text-base);line-height:var(--leading-normal);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}h1,h2,h3,h4{font-family:var(--font-display);color:var(--text-strong);line-height:var(--leading-tight);letter-spacing:var(--tracking-tight);font-weight:var(--weight-semibold);margin:0 0 var(--space-3)}p{margin:0 0 var(--space-3)}a{color:var(--text-link);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--text-link) 35%,transparent);transition:var(--transition-fast)}a:hover{color:var(--wind-700);border-bottom-color:var(--wind-700)}code,kbd,samp,pre{font-family:var(--font-code);font-size:.92em}.hn-eyebrow{font-family:var(--font-mono);font-size:var(--text-2xs);font-weight:var(--weight-medium);letter-spacing:var(--tracking-caps);text-transform:uppercase;color:var(--text-muted)}::selection{background:var(--brass-100);color:var(--ink-900)}html,body{margin:0;height:100%;background:var(--surface-page)}#root{height:100vh;height:100dvh;overflow:hidden;max-width:100%}.hn-dynamic-viewport{height:100vh;height:100dvh;min-height:100vh;min-height:100dvh}button:focus-visible,a[href]:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[role=button]:focus-visible,[role=tab]:focus-visible,[role=checkbox]:focus-visible,[role=radio]:focus-visible,[role=switch]:focus-visible,[role=separator]:focus-visible{outline:2px solid var(--border-focus)!important;outline-offset:2px}.hn-select select:focus,.hn-select select:focus-visible{outline:none!important}.hn-shell{display:flex;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;background:var(--surface-page);color:var(--text-body)}.hn-shell-sidebar{width:var(--sidebar-w);flex:0 0 auto;display:flex;min-height:0;flex-direction:column;box-sizing:border-box;border-right:1px solid var(--border-hair);background:var(--bone-100);padding:18px 14px}.hn-shell-wordmark{padding:2px 4px 20px}.hn-shell-workspace{padding:0 10px 8px}.hn-shell-nav{display:flex;min-height:0;flex-direction:column;gap:2px;overflow-y:auto}.hn-shell-column{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column}.hn-shell-topbar{min-height:var(--topbar-h);flex:0 0 auto;display:flex;align-items:center;gap:16px;padding:0 22px;border-bottom:1px solid var(--border-hair);background:color-mix(in srgb,var(--bone-100) 80%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);position:relative;z-index:90}.hn-shell-menu{display:none;width:var(--touch-target);height:var(--touch-target);flex:0 0 auto;align-items:center;justify-content:center;border:1px solid var(--border-hair);border-radius:var(--radius-sm);background:var(--surface-card);color:var(--text-body)}.hn-shell-heading{min-width:0}.hn-shell-tools{margin-left:auto;display:flex;min-width:0;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:10px}.hn-shell-search{width:220px}.hn-shell-main{flex:1;min-width:0;min-height:0;overflow-x:hidden;overflow-y:auto}.hn-shell-content{width:100%;min-width:0;min-height:100%;margin:0 auto;padding:var(--page-gutter-y) var(--page-gutter-x) calc(32px + var(--safe-bottom));box-sizing:border-box;display:flex;flex-direction:column}.hn-shell-backdrop{display:none}.hn-viewport-popover{box-sizing:border-box;max-width:calc(100vw - var(--safe-left) - var(--safe-right) - 28px)}.hn-modal-overlay{box-sizing:border-box;padding:calc(24px + var(--safe-top)) calc(24px + var(--safe-right)) calc(24px + var(--safe-bottom)) calc(24px + var(--safe-left))}.hn-modal-panel{min-width:0}.hn-modal-footer{flex-wrap:wrap;padding-bottom:calc(14px + var(--safe-bottom))}.hn-board-local-overflow{max-width:100%;overscroll-behavior-inline:contain}.hn-timeline-scroll{overscroll-behavior-inline:contain;-webkit-overflow-scrolling:touch}.hn-row-actions{flex-wrap:wrap}.hn-topbar-label-short{display:none}.hn-grid-mobile,.hn-stack-mobile,.hn-wrap-mobile,.hn-dense-row,.hn-vps-row{min-width:0}.hn-vps-row:hover{background:var(--surface-sunken)}.hn-vps-main{display:flex;align-items:center;gap:12px;min-width:0;flex-wrap:wrap}.hn-vps-actions{display:flex;align-items:center;gap:4px;margin-left:auto;flex-shrink:0}.hn-vps-sep{width:1px;height:18px;margin:0 4px;background:var(--border-hair)}@media (max-width: 1199px){.hn-vps-actions{flex-wrap:wrap;justify-content:flex-end}}.hn-nav-badge{margin-left:auto;flex-shrink:0;min-width:18px;height:18px;padding:0 5px;display:inline-flex;align-items:center;justify-content:center;background:var(--brass-700);color:var(--bone-000);border-radius:var(--radius-pill);font-family:var(--font-mono);font-size:var(--text-2xs);font-weight:var(--weight-semibold);line-height:1}@media (min-width: 768px) and (max-width: 1199px){.hn-shell-sidebar{width:var(--sidebar-w);padding:14px 8px}.hn-shell-sidebar .hn-nav-badge{margin-left:0}.hn-shell-sidebar .hn-nav-label,.hn-shell-sidebar .hn-shell-workspace,.hn-shell-sidebar .hn-shell-wordmark>div>div>span:last-child{display:none}.hn-shell-sidebar nav button{justify-content:center;padding-inline:0}.hn-shell-wordmark{display:flex;justify-content:center;padding-inline:0}}@media (max-width: 767px){.hn-shell-menu{display:inline-flex}.hn-shell-sidebar{position:fixed;z-index:120;inset:0 auto 0 0;width:min(320px,calc(100vw - 48px));padding:calc(14px + var(--safe-top)) 14px calc(14px + var(--safe-bottom)) calc(14px + var(--safe-left));box-shadow:var(--shadow-xl);transform:translate(-105%);transition:transform var(--transition-fast)}.hn-shell[data-nav-open=true] .hn-shell-sidebar{transform:translate(0)}.hn-shell-backdrop{display:block;position:fixed;z-index:119;top:0;right:0;bottom:0;left:0;width:100%;height:100%;border:0;background:color-mix(in srgb,var(--ink-900) 42%,transparent)}.hn-shell-topbar{align-items:flex-start;flex-wrap:wrap;gap:8px 10px;padding:calc(6px + var(--safe-top)) var(--page-gutter-x) 8px;-webkit-backdrop-filter:none;backdrop-filter:none}.hn-shell-heading{flex:1 1 calc(100% - 54px);align-self:center}.hn-shell-tools{flex:1 1 100%;margin-left:0;justify-content:flex-start;gap:6px}.hn-shell-search{flex:1 1 100%;width:100%}.hn-topbar-label{display:none}.hn-topbar-label-short{display:inline}.hn-shell button{min-width:var(--touch-target);min-height:var(--touch-target)}.hn-viewport-popover{position:fixed!important;inset:auto max(var(--page-gutter-x),var(--safe-right)) calc(var(--page-gutter-y) + var(--safe-bottom)) max(var(--page-gutter-x),var(--safe-left))!important;width:auto!important;max-width:none;max-height:calc(100dvh - var(--safe-top) - var(--safe-bottom) - var(--page-gutter-y) - var(--page-gutter-y))!important;overflow:auto}.hn-modal-overlay{align-items:flex-end!important;padding:var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left)}.hn-modal-panel{width:100%!important;max-width:100%!important;max-height:calc(100dvh - var(--safe-top) - var(--safe-bottom))!important;border-radius:var(--radius-lg) var(--radius-lg) 0 0!important}.hn-modal-header,.hn-modal-body,.hn-modal-footer{padding-inline:var(--page-gutter-x)!important}.hn-modal-footer>*{min-height:var(--touch-target)}.hn-stat-grid{grid-template-columns:repeat(2,minmax(0,1fr))!important}.hn-project-header{display:none!important}.hn-project-row{grid-template-columns:minmax(0,1fr)!important;align-items:stretch!important;gap:10px!important;margin-bottom:10px;padding:14px!important;border:1px solid var(--border-hair);border-left-width:3px;border-radius:var(--radius-md)}.hn-project-row>[data-label]{min-width:0}.hn-project-row>[data-label]:before{content:attr(data-label);display:block;margin-bottom:4px;color:var(--text-subtle);font:var(--weight-semibold) var(--text-2xs)/1.2 var(--font-mono);letter-spacing:.08em;text-transform:uppercase}.hn-project-row>[data-label=Aktivitas]{white-space:normal!important}.hn-backlog-topline,.hn-team-topline,.hn-backlog-view-actions,.hn-team-view-actions,.hn-backlog-filters,.hn-team-filters{align-items:stretch!important}.hn-backlog-topline>*,.hn-team-topline>*,.hn-backlog-view-actions>*,.hn-team-view-actions>*,.hn-backlog-filters>*,.hn-team-filters>*{max-width:100%}.hn-backlog-view-actions,.hn-team-view-actions{flex-wrap:wrap}.hn-backlog-filters .hn-touch-target,.hn-team-filters .hn-touch-target{flex:1 1 145px!important;width:auto!important}.hn-backlog-grid{grid-template-columns:minmax(0,1fr)!important}.hn-backlog-row{align-items:flex-start!important;flex-wrap:wrap}.hn-backlog-row>div{flex-basis:100%!important}.hn-card-footer{align-items:flex-start!important;flex-direction:column}.hn-grid-mobile{grid-template-columns:minmax(0,1fr)!important}.hn-stack-mobile{align-items:stretch!important;flex-direction:column}.hn-wrap-mobile,.hn-dense-row{align-items:flex-start!important;flex-wrap:wrap}.hn-vps-main{align-items:flex-start;gap:8px}.hn-vps-main>button{flex:1 1 100%}.hn-vps-pills{flex-wrap:wrap}.hn-vps-actions{margin-left:0;width:100%;justify-content:flex-start}.hn-vps-actions>button{flex:1 1 auto}.hn-vps-sep{display:none}.hn-dense-row>[style*="flex: 1"]{min-width:min(220px,100%)}.hn-picker-row{flex-wrap:wrap}.hn-picker-row>.hn-picker-title{order:2;flex:1 1 100%!important;min-width:100%!important;white-space:normal!important;overflow:visible!important}.hn-card-header{align-items:stretch!important;flex-direction:column}.hn-card-actions{max-width:100%}.hn-card-actions>*{max-width:100%}.hn-settings-layout{width:100%}.hn-portal-header{height:auto!important;min-height:var(--topbar-h);flex-wrap:wrap;padding:max(8px,var(--safe-top)) max(var(--page-gutter-x),var(--safe-right)) 8px max(var(--page-gutter-x),var(--safe-left))!important}.hn-portal-header>div{flex-basis:1px}.hn-portal-content{box-sizing:border-box;padding:16px max(var(--page-gutter-x),var(--safe-right)) calc(24px + var(--safe-bottom)) max(var(--page-gutter-x),var(--safe-left))!important}.hn-portal-toolbar{align-items:stretch!important;flex-direction:column}.hn-portal-row{align-items:flex-start!important;flex-wrap:wrap;min-height:var(--touch-target)}.hn-portal-row>span:nth-child(2){flex-basis:calc(100% - 110px)}}.hn-responsive-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:10px;min-width:0;max-width:100%}@media (max-width: 767px){.hn-setting-row{align-items:stretch!important;flex-direction:column}.hn-setting-control{width:100%}.hn-setting-control>.hn-touch-target,.hn-setting-control>div{width:100%!important;max-width:100%}.hn-setting-control>div{flex-wrap:wrap}.hn-setting-control>div>div.hn-touch-target{flex:1 1 200px;width:auto!important;max-width:100%}}.hn-local-overflow{max-width:100%;min-width:0;overflow:auto;overscroll-behavior-inline:contain;-webkit-overflow-scrolling:touch}.hn-tabs{max-width:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior-inline:contain}.hn-ide-head{display:flex;align-items:center;flex-wrap:wrap;gap:12px;min-width:0}.hn-ide-head>.hn-tabs{flex:0 0 auto}.hn-ide-toolbar{display:flex;align-items:center;flex:1 1 480px;flex-wrap:nowrap;gap:10px;min-width:0;max-width:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior-inline:contain}.hn-ide-toolbar>*{flex:0 0 auto}.hn-ide-toolbar>:first-child{margin-inline-start:auto}@media (pointer: coarse),(max-width: 767px){button:not(.hn-shell-backdrop){min-width:var(--touch-target);min-height:var(--touch-target)}input,select,textarea{min-width:var(--touch-target);min-height:var(--touch-target)}.hn-touch-target,.hn-project-open,.hn-terminal-unplaced-action,[role=button][tabindex="0"]{min-width:var(--touch-target)!important;min-height:var(--touch-target)!important}.hn-tabs [role=tab]{min-height:var(--touch-target)}.hn-choice-target{min-width:var(--touch-target);min-height:var(--touch-target)}.hn-choice-control{min-width:var(--touch-target);min-height:var(--touch-target);outline-offset:8px}}.hn-responsive-panels{display:flex;flex:1 1 auto;min-width:0;min-height:0;flex-direction:column;gap:12px}.hn-panel-switcher{flex:0 0 auto;max-width:100%;overflow-x:auto;overscroll-behavior-inline:contain}.hn-panels-grid{display:grid;grid-template-columns:minmax(0,1fr);flex:1 1 auto;min-width:0;min-height:0;gap:16px}.hn-responsive-panel{min-width:0;min-height:0}.hn-panel-flex{display:flex;min-width:0;min-height:0;flex-direction:column}.hn-panel-flex>*{min-width:0}.hn-graph-action{display:inline-grid;min-width:28px;min-height:28px;place-items:center;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text-muted);cursor:pointer}.hn-graph-action:hover{background:var(--bone-200)}.hn-terminal-actions{display:inline-flex;flex:0 0 auto;align-items:center;gap:2px}.hn-terminal-action{display:inline-grid;min-width:28px;min-height:28px;padding:0;place-items:center;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text-subtle);font:inherit;cursor:pointer}.hn-terminal-action--text{padding-inline:5px}.hn-terminal-action:hover{background:var(--bone-300);color:var(--text-strong)}.hn-terminal-gutter{border:0;padding:0;font:inherit;background:transparent;color:var(--text-subtle)}.hn-terminal-gutter:hover:not(:disabled){background:var(--bone-300);color:var(--text-strong)}@media (pointer: coarse){.hn-terminal-gutter--col:before{content:"";position:absolute;left:0;right:0;top:calc((var(--touch-target) - 100%) / -2);bottom:calc((var(--touch-target) - 100%) / -2)}.hn-terminal-gutter--row:before{content:"";position:absolute;top:0;bottom:0;left:calc((var(--touch-target) - 100%) / -2);right:calc((var(--touch-target) - 100%) / -2)}}.hn-terminal-unplaced-chip{padding:4px 8px;gap:6px}@media (pointer: coarse),(max-width: 767px){.hn-terminal-unplaced-chip{padding:6px 6px 6px 10px;gap:8px}}.hn-terminal-select-overlay{position:absolute;top:8px;right:8px;bottom:8px;left:8px;display:flex;flex-direction:column;align-items:center;justify-content:space-between;pointer-events:none}.hn-terminal-select-badge{padding:3px 10px;border:1px solid var(--brass-500);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--brass-500) 18%,var(--term-bg));color:var(--brass-300);font:var(--weight-medium) var(--text-xs)/1.2 var(--font-mono)}.hn-terminal-select-bar{pointer-events:auto;display:inline-flex;gap:6px;padding:4px;border:1px solid var(--border-hair);border-radius:var(--radius-md);background:var(--surface-card);box-shadow:var(--shadow-sm)}.hn-terminal-select-bar .hn-terminal-action{color:var(--text-body)}.hn-terminal-keys{display:flex;flex:0 0 auto;gap:4px;max-width:100%;padding:4px 2px;overflow-x:auto;overscroll-behavior-inline:contain;border-top:1px solid var(--border-hair)}.hn-terminal-key{flex:0 0 auto;min-width:40px;min-height:32px;padding:0 8px;border:1px solid var(--border-hair);border-radius:var(--radius-sm);background:var(--surface-card);color:var(--text-body);font:var(--weight-medium) var(--text-sm)/1 var(--font-mono);cursor:pointer}.hn-terminal-key:hover{background:var(--bone-200);color:var(--text-strong)}.hn-terminal-composer{display:flex;flex:0 0 auto;flex-wrap:wrap;align-items:center;gap:6px;padding:4px 2px;border-top:1px solid var(--border-hair)}.hn-terminal-composer-status{flex:0 0 auto;font:var(--text-xs)/1.2 var(--font-mono);color:var(--text-subtle);white-space:nowrap}.hn-terminal-composer-status--queued{color:var(--status-warn)}.hn-terminal-composer-status--held{color:var(--status-err)}.hn-terminal-voice{display:flex;flex:0 0 auto;flex-wrap:wrap;align-items:center;gap:6px;padding:4px 2px;border-top:1px solid var(--border-hair)}.hn-terminal-voice-lang{flex:0 0 auto;min-height:30px;padding:0 6px;border:1px solid var(--border-hair);border-radius:var(--radius-sm);background:var(--surface-card);color:var(--text-body);font:var(--text-xs)/1.2 var(--font-mono)}.hn-terminal-voice-hint{display:inline-flex;color:var(--text-subtle);cursor:help}.hn-terminal-voice-interim{flex:1 1 120px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:italic var(--text-xs)/1.2 var(--font-mono);color:var(--text-subtle)}.hn-terminal-voice-error{font:var(--text-xs)/1.2 var(--font-mono);color:var(--status-err)}.hn-voice-rec{animation:hn-voice-pulse 1.2s ease-in-out infinite}@keyframes hn-voice-pulse{50%{box-shadow:0 0 0 4px var(--status-err-tint)}}@media (prefers-reduced-motion: reduce){.hn-voice-rec{animation:none}}.hn-terminal-divider{position:relative;background:transparent;z-index:1}.hn-terminal-divider:before{content:"";position:absolute;background:var(--accent-hover)}.hn-terminal-divider--col{width:16px;margin-left:-12px;justify-self:start;cursor:col-resize}.hn-terminal-divider--col:before{top:0;bottom:0;left:50%;width:1px;transform:translate(-50%)}.hn-terminal-divider--row{height:16px;margin-top:-12px;align-self:start;cursor:row-resize}.hn-terminal-divider--row:before{left:0;right:0;top:50%;height:1px;transform:translateY(-50%)}.hn-terminal-divider:hover:before,.hn-terminal-divider:focus-visible:before{background:var(--accent-press)}.hn-terminal-divider[aria-disabled=true]{cursor:default}.hn-terminal-divider[aria-disabled=true]:hover:before{background:var(--accent-hover)}@media (max-width: 767px){.hn-terminal-cell-header{flex-wrap:wrap}}@media (pointer: coarse),(max-width: 767px){.hn-graph-action,.hn-terminal-action,.hn-terminal-key,.hn-terminal-group-control{min-width:var(--touch-target);min-height:var(--touch-target)}}.hn-responsive-panel[aria-hidden=true]{display:none}@media (min-width: 768px){.hn-responsive-panels--tablet .hn-panel-switcher{display:none}.hn-responsive-panels--tablet .hn-panels-grid{grid-template-columns:minmax(0,var(--hn-master-width, 280px)) minmax(0,1fr)}.hn-responsive-panels--tablet .hn-responsive-panel[aria-hidden=true]{display:block}}@media (min-width: 1200px){.hn-responsive-panels--desktop .hn-panel-switcher{display:none}.hn-responsive-panels--desktop .hn-panels-grid{grid-template-columns:minmax(0,var(--hn-master-width, 300px)) minmax(0,1fr)}.hn-responsive-panels--desktop .hn-responsive-panel[aria-hidden=true]{display:block}}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation:none!important;scroll-behavior:auto!important;transition:none!important}}button{--accent-on: #fff}a{color:var(--text-link);text-decoration:none}a:hover{color:var(--wind-700);text-decoration:underline}.hn-md{color:var(--text-body);font-family:var(--font-sans);font-size:15px;line-height:1.72;overflow-wrap:anywhere}.hn-md>:first-child{margin-top:8px}.hn-md h1,.hn-md h2,.hn-md h3,.hn-md h4{font-family:var(--font-display);font-weight:600;letter-spacing:-.02em;color:var(--ink-900);line-height:1.2;margin:1.6em 0 .5em}.hn-md h1{font-size:30px;margin-top:.4em;padding-bottom:.34em;border-bottom:1px solid var(--border-hair)}.hn-md h2{font-size:22px}.hn-md h3{font-size:18px}.hn-md h4{font-size:15px}.hn-md p{margin:.7em 0}.hn-md ul,.hn-md ol{margin:.6em 0;padding-left:1.5em}.hn-md li{margin:.28em 0}.hn-md li::marker{color:var(--brass-500)}.hn-md ul.contains-task-list,.hn-md li.task-list-item{list-style:none}.hn-md li.task-list-item{padding-left:0}.hn-md input[type=checkbox]{accent-color:var(--brass-500);margin-right:8px;transform:translateY(1px)}.hn-md strong{font-weight:600;color:var(--ink-900)}.hn-md em{color:var(--text-muted)}.hn-md a{color:var(--text-link)}.hn-md hr{border:none;border-top:1px solid var(--border-hair);margin:1.6em 0}.hn-md code{font-family:var(--font-mono);font-size:.86em;background:var(--bone-200);color:var(--ink-800);padding:1.5px 5px;border-radius:var(--radius-xs);border:1px solid var(--border-hair)}.hn-md pre{background:var(--surface-code);border:1px solid var(--term-line);border-radius:var(--radius-lg);padding:14px 16px;overflow:auto;margin:1em 0;white-space:pre-wrap;overflow-wrap:anywhere}.hn-md pre code{background:transparent;border:none;padding:0;color:var(--term-fg);font-size:12.5px;line-height:1.7}.hn-md blockquote{margin:1em 0;padding:4px 16px;border-left:3px solid var(--brass-500);background:var(--brass-050);color:var(--text-body);border-radius:0 var(--radius-sm) var(--radius-sm) 0}.hn-md blockquote p{margin:.4em 0}.hn-md table{border-collapse:collapse;width:100%;margin:1em 0;font-size:14px;table-layout:fixed}.hn-md th,.hn-md td{overflow-wrap:anywhere}.hn-md th{font-family:var(--font-mono);font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);text-align:left;padding:8px 12px;background:var(--bone-100);border:1px solid var(--border-hair)}.hn-md td{padding:8px 12px;border:1px solid var(--border-hair);color:var(--text-body)}.hn-md td code{font-size:.82em}.hn-md img{max-width:100%;border-radius:var(--radius-sm)}@keyframes hn-fade-in{0%{opacity:0}to{opacity:1}}@keyframes hn-modal-in{0%{opacity:0;transform:translateY(8px) scale(.99)}to{opacity:1;transform:none}}@keyframes hn-toast-in{0%{opacity:0;transform:translate(-50%,10px)}to{opacity:1;transform:translate(-50%)}}.hn-pet-reactor{transform-origin:50% 86%}.hn-pet-stage:not([data-reduced-motion=true]):hover .hn-pet-reactor{transform:translateY(-2px) scale(1.035) rotate(-1deg)}.hn-pet-rowshift{transform:translateY(calc(var(--row, 0) * -100%))}.hn-pet-hit{touch-action:none;user-select:none;-webkit-user-select:none}@keyframes hn-pet-frames{to{transform:translate(-100%)}}.hn-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}@keyframes hn-pet-click{0%,to{transform:translateY(0) scale(1) rotate(0)}38%{transform:translateY(2px) scale(.9,1.06) rotate(-2deg)}72%{transform:translateY(-3px) scale(1.06,.96) rotate(1.5deg)}}@keyframes hn-pet-panel-in{0%{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes hn-pet-panel-out{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(5px) scale(.985)}}@keyframes hn-pet-reveal{0%{opacity:0;transform:translateY(7px) scale(.86)}70%{opacity:1;transform:translateY(-1px) scale(1.035)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes hn-pet-bubble-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes hn-pet-heart{0%{opacity:0;transform:translateY(0) scale(.6)}30%{opacity:1;transform:translateY(-8px) scale(1)}to{opacity:0;transform:translateY(-26px) scale(.9)}}.hn-dalang{border:1px solid var(--border-hair);border-radius:var(--radius-lg);background:var(--surface-card);overflow:hidden;margin-bottom:20px}.hn-dalang-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:16px 20px 10px}.hn-dalang-stats{display:flex;gap:22px;flex-wrap:wrap}.hn-dalang-stat{text-align:right}.hn-dalang-stat>div:first-child{justify-content:flex-end}.hn-dalang-stage{position:relative;display:flex;align-items:flex-end;gap:16px;min-height:148px;padding:6px 20px 0;background:linear-gradient(180deg,var(--bone-000),var(--bone-200))}.hn-dalang-stage[data-live]{min-height:196px;padding-top:30px;background:radial-gradient(ellipse 85% 130% at 50% -25%,color-mix(in srgb,var(--brass-400) 24%,var(--term-bg)),var(--term-bg) 64%)}.hn-dalang-stage[data-live] .hn-dalang-mascot img{filter:drop-shadow(0 0 20px color-mix(in srgb,var(--bone-000) 32%,transparent))}.hn-dalang-stage[data-live] .hn-dalang-live{border-color:color-mix(in srgb,var(--brass-500) 45%,var(--term-line))}.hn-dalang-stage[data-live] .hn-dalang-live[data-waiting]{border-color:var(--amber-600)}.hn-dalang-stage[data-live] .hn-dalang-puppet img{filter:drop-shadow(0 0 10px color-mix(in srgb,var(--brass-300) 55%,transparent))}.hn-dalang-threads{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none}.hn-dalang-threads path{fill:none;stroke:var(--brass-400);stroke-width:1.5;stroke-linecap:round;stroke-dasharray:5 9;opacity:.75;animation:hn-dalang-flow 1.4s linear infinite}@keyframes hn-dalang-flow{to{stroke-dashoffset:-28}}.hn-dalang-mascot{width:172px;flex:0 0 auto}.hn-dalang-blencong{height:44px;width:auto;flex:0 0 auto;pointer-events:none}.hn-dalang-blencong[data-lit]{filter:drop-shadow(0 0 14px color-mix(in srgb,var(--brass-400) 65%,transparent))}.hn-dalang-troupe{flex:1;display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end;padding:4px 0 14px}.hn-dalang-live{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;text-align:left;cursor:pointer;width:168px;background:var(--term-bg);border:1px solid var(--term-line);border-radius:var(--radius-md);padding:8px 12px 10px;box-shadow:var(--shadow-sm),0 0 16px color-mix(in srgb,var(--brass-500) 28%,transparent);transition:box-shadow var(--dur-base) var(--ease-out),transform var(--dur-base) var(--ease-out)}.hn-dalang-live:hover{transform:translateY(-2px);box-shadow:var(--shadow-md),0 0 22px color-mix(in srgb,var(--brass-500) 42%,transparent)}.hn-dalang-live:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}.hn-dalang-puppet{display:block;width:fit-content;margin:0 auto 6px;transform-origin:50% 100%;animation:hn-dalang-sway 3.8s var(--ease-inout) infinite alternate}@keyframes hn-dalang-sway{0%{transform:rotate(-2.4deg)}to{transform:rotate(2.4deg)}}.hn-dalang-puppet--still{animation:none;transform:rotate(-3deg)}.hn-dalang-live[data-waiting]{border-color:var(--amber-600);box-shadow:var(--shadow-sm),0 0 16px color-mix(in srgb,var(--amber-500) 30%,transparent)}.hn-dalang-empty{flex:1;padding:22px 0 26px}.hn-dalang-debog{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:10px 20px 12px;border-top:1px solid var(--border-hair);background:var(--bone-100)}.hn-dalang-parked{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;cursor:pointer;display:inline-flex;align-items:center;gap:7px;padding:4px 12px 4px 8px;background:var(--surface-card);border:1px solid var(--border-hair);border-radius:var(--radius-pill);transition:border-color var(--dur-fast) var(--ease-out)}.hn-dalang-parked:hover{border-color:var(--bone-400)}.hn-dalang-parked:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}.hn-dlg{position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;overflow-y:auto;overscroll-behavior:contain;background:linear-gradient(180deg,var(--term-bg),#0d0b07 60%);padding:20px 26px 12px;color:var(--term-fg);padding-bottom:max(12px,var(--safe-bottom, 0px))}.hn-dlg-top{display:flex;align-items:center;justify-content:space-between;gap:14px}.hn-dlg-blencong{height:44px;width:auto;flex:0 0 auto}.hn-dlg-blencong[data-lit]{filter:drop-shadow(0 0 12px rgba(207,157,85,.65))}.hn-dlg-title{font-family:var(--font-display);font-size:21px;font-weight:600;color:var(--term-fg);margin:0}.hn-dlg-boot{margin:4px 0 0;font-family:var(--font-mono);font-size:11px;letter-spacing:.06em;color:var(--brass-300);min-height:15px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.hn-dlg-boot:after{content:"▍";color:var(--brass-500);margin-left:2px;animation:hn-dlg-blink 1s steps(1) infinite}@keyframes hn-dlg-blink{50%{opacity:0}}.hn-dlg-chips{display:flex;gap:8px;flex:0 0 auto}.hn-dlg-chip{display:inline-flex;align-items:center;gap:7px;padding:7px 12px;border:1px solid var(--term-line);border-radius:var(--radius-md);background:#fffdf808;font-family:var(--font-mono);font-size:12px;color:var(--brass-300);white-space:nowrap;font-variant-numeric:tabular-nums}.hn-dlg-exit{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;cursor:pointer;width:34px;height:34px;flex:none;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--term-line);border-radius:var(--radius-md);background:#fffdf808;color:var(--term-dim);transition:color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}.hn-dlg-exit:hover{color:var(--term-fg);border-color:var(--brass-700)}.hn-dlg-exit:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}.hn-dlg-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-top:16px}.hn-dlg-kpi{display:flex;gap:11px;align-items:flex-start;min-width:0;padding:12px 14px;border:1px solid var(--term-line);border-radius:var(--radius-md);background:#fffdf808}.hn-dlg-kpi-ic{width:34px;height:34px;border-radius:var(--radius-sm);display:inline-flex;align-items:center;justify-content:center;flex:none}.hn-dlg-tone-wind{background:#517f8c2e;color:var(--wind-500)}.hn-dlg-tone-leaf{background:#5f83402e;color:var(--leaf-500)}.hn-dlg-tone-brass{background:#b8863b2e;color:var(--brass-400)}.hn-dlg-tone-amber{background:#cf8f282e;color:var(--amber-500)}.hn-dlg-kpi-l{display:block;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.12em;color:var(--term-dim)}.hn-dlg-kpi-v{display:block;font-family:var(--font-display);font-size:25px;font-weight:700;line-height:1.15;color:var(--term-fg);font-variant-numeric:tabular-nums}.hn-dlg-kpi-s{display:block;font-size:10.5px;color:var(--term-dim);margin-top:1px}.hn-dlg-grid{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:14px;align-items:start;margin-top:14px}.hn-dlg-hero{position:relative;overflow:hidden;border:1px solid var(--term-line);border-radius:var(--radius-lg);background:radial-gradient(ellipse 75% 95% at 50% 0%,#cf9d5533,#0000 62%);padding:16px 16px 0}.hn-dlg-hud{position:absolute;left:50%;top:128px;transform:translate(-50%,-50%);width:300px;height:300px;pointer-events:none;opacity:.5}.hn-dlg-hud circle{fill:none;stroke:var(--brass-700);stroke-width:1}.hn-dlg-hud-a,.hn-dlg-hud-b{transform-origin:50% 50%}.hn-dlg-hud-a{animation:hn-dlg-rot 26s linear infinite}.hn-dlg-hud-b{animation:hn-dlg-rotr 40s linear infinite}@keyframes hn-dlg-rot{to{transform:rotate(360deg)}}@keyframes hn-dlg-rotr{to{transform:rotate(-360deg)}}.hn-dlg-threads{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none}.hn-dlg-threads path{fill:none;stroke:var(--brass-500);stroke-width:1.4;stroke-linecap:round;stroke-dasharray:4 8;opacity:.8;animation:hn-dalang-flow 1.5s linear infinite}.hn-dlg-threads path.hn-dlg-thread--slack{stroke:var(--brass-700);stroke-dasharray:none;opacity:.3;animation:none}.hn-dlg-scan{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;background:linear-gradient(180deg,#0000,#cf9d550d 48%,#e3c98817,#cf9d550d 52%,#0000);background-size:100% 240px;background-repeat:no-repeat;background-position:0 -240px;animation:hn-dlg-scan 7s linear infinite}@keyframes hn-dlg-scan{0%{background-position:0 -240px}60%{background-position:0 460px}to{background-position:0 460px}}.hn-dlg-hero-art{position:relative;width:min(540px,94%);aspect-ratio:835 / 582;margin:0 auto;animation:hn-dlg-float 6s ease-in-out infinite}.hn-dlg-hero-art img{position:absolute;display:block;height:auto;filter:drop-shadow(0 0 18px rgba(212,164,60,.35))}.hn-dlg-rig-body{left:25.88%;top:16.32%;width:48.73%;z-index:2}.hn-dlg-rig-arm{z-index:1;will-change:transform}.hn-dlg-rig-arm--ul{left:5.48%;top:.39%;width:32.03%;transform-origin:85.5% 86.8%;animation:hn-dlg-arm-a 5s ease-in-out infinite}.hn-dlg-rig-arm--ur{left:61.65%;top:0%;width:30.82%;transform-origin:15.1% 87.1%;animation:hn-dlg-arm-b 5.6s ease-in-out infinite}.hn-dlg-rig-arm--ml{left:0%;top:58.84%;width:37.36%;transform-origin:89.2% 24.2%;animation:hn-dlg-arm-b 6.4s ease-in-out infinite}.hn-dlg-rig-arm--mr{left:61.8%;top:58.32%;width:38.2%;transform-origin:11.1% 24.3%;animation:hn-dlg-arm-a 7s ease-in-out infinite}@keyframes hn-dlg-arm-a{0%,to{transform:rotate(-2.5deg)}50%{transform:rotate(3deg)}}@keyframes hn-dlg-arm-b{0%,to{transform:rotate(2.5deg)}50%{transform:rotate(-3deg)}}.hn-dlg-hand{position:absolute;width:2px;height:2px;pointer-events:none}.hn-dlg-hand[data-hand=ul]{left:15.5%;top:9.9%}.hn-dlg-hand[data-hand=ur]{left:82.7%;top:9.6%}.hn-dlg-hand[data-hand=ml]{left:10.2%;top:76.1%}.hn-dlg-hand[data-hand=mr]{left:89.5%;top:75.5%}@keyframes hn-dlg-float{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.hn-dlg-cards{position:relative;display:flex;flex-wrap:wrap;gap:12px;align-items:stretch;justify-content:center;padding:18px 0 16px}.hn-dlg-prj{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;text-align:left;cursor:pointer;width:168px;background:#0a0805d9;border:1px solid rgba(184,134,59,.45);border-radius:var(--radius-md);padding:8px 12px 10px;color:var(--term-fg);box-shadow:0 0 16px #b8863b38;transition:transform var(--dur-base) var(--ease-out),box-shadow var(--dur-base) var(--ease-out)}.hn-dlg-prj:hover{transform:translateY(-3px);box-shadow:0 0 24px #b8863b66}.hn-dlg-prj:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}.hn-dlg-prj[data-waiting]{border-color:var(--amber-600);box-shadow:0 0 16px #cf8f284d}.hn-dlg-prj--off{border-color:var(--term-line);box-shadow:none}.hn-dlg-prj--off:hover{box-shadow:0 0 14px #b8863b24}.hn-dlg-prj--off .hn-dlg-puppet img{filter:grayscale(.85) brightness(.55)}.hn-dlg-prj--off .hn-dlg-prj-name,.hn-dlg-prj-sub--off{color:var(--term-dim)}.hn-dlg-puppet{display:block;width:fit-content;margin:0 auto 6px;transform-origin:50% 0%;animation:hn-dalang-sway 3.6s var(--ease-inout) infinite alternate}.hn-dlg-puppet--still{animation:none;transform:rotate(-3deg)}.hn-dlg-puppet img{display:block;height:108px;width:auto;filter:drop-shadow(0 0 10px rgba(227,201,136,.5))}.hn-dlg-prj--off .hn-dlg-puppet img{height:88px}.hn-dlg-prj-name{display:block;font-family:var(--font-mono);font-size:12px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hn-dlg-prj-sub{display:block;font-family:var(--font-mono);font-size:10.5px;color:var(--brass-400);margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hn-dlg-prj-sub--amber{color:var(--amber-500)}.hn-dlg-empty{position:relative;text-align:center;padding:26px 0 30px;color:var(--term-dim);font-size:12.5px;line-height:1.7}.hn-dlg-cmd{-webkit-appearance:none;-moz-appearance:none;appearance:none;font:inherit;cursor:pointer;width:100%;margin-top:12px;display:flex;align-items:center;gap:12px;padding:11px 15px;text-align:left;border:1px solid var(--brass-700);border-radius:var(--radius-lg);background:linear-gradient(90deg,#d4a43c1f,#d4a43c08);color:var(--term-fg);transition:border-color var(--dur-base) var(--ease-out)}.hn-dlg-cmd:hover{border-color:var(--brass-500)}.hn-dlg-cmd:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px}.hn-dlg-mic{position:relative;width:11px;height:11px;border-radius:50%;background:var(--brass-500);flex:none}.hn-dlg-mic:before{content:"";position:absolute;top:-5px;right:-5px;bottom:-5px;left:-5px;border-radius:50%;border:1px solid var(--brass-500);opacity:0;animation:hn-dlg-ping 1.8s ease-out infinite}@keyframes hn-dlg-ping{0%{transform:scale(.85);opacity:.8}70%{transform:scale(1.4);opacity:0}to{opacity:0}}.hn-dlg-cmd-t{font-family:var(--font-mono);font-size:12px;color:var(--term-dim);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hn-dlg-cmd-t b{color:var(--brass-300);font-weight:500}.hn-dlg-cmd-k{margin-left:auto;flex:none;font-family:var(--font-mono);font-size:10px;color:var(--term-dim);border:1px solid var(--term-line);border-radius:var(--radius-sm);padding:2px 8px}.hn-dlg-rail{display:flex;flex-direction:column;gap:12px;min-width:0}.hn-dlg-card{border:1px solid var(--term-line);border-radius:var(--radius-md);background:#fffdf808;padding:12px 14px}.hn-dlg-rt{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.12em;color:var(--brass-300);margin-bottom:9px}.hn-dlg-mut{font-size:12px;color:var(--term-dim)}.hn-dlg-act{display:flex;gap:9px;align-items:flex-start;padding:6px 0;border-bottom:1px solid var(--term-line);font-size:11.5px}.hn-dlg-act:last-of-type{border-bottom:0}.hn-dlg-dot{width:7px;height:7px;border-radius:50%;background:var(--term-line);flex:none;margin-top:4px}.hn-dlg-dot--on{background:var(--brass-500)}.hn-dlg-act-x{color:var(--term-dim);line-height:1.5;min-width:0;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.hn-dlg-act-x b{color:var(--term-fg);font-family:var(--font-mono);font-size:11px;font-weight:500}.hn-dlg-donut-wrap{display:flex;align-items:center;gap:12px}.hn-dlg-donut{position:relative;width:112px;height:112px;flex:none}.hn-dlg-ring{fill:none;stroke:var(--term-line)}.hn-dlg-seg{fill:none;transition:stroke-dasharray var(--dur-slow) var(--ease-out)}.hn-dlg-seg--wind{stroke:var(--wind-500)}.hn-dlg-seg--leaf{stroke:var(--leaf-500)}.hn-dlg-seg--amber{stroke:var(--amber-500)}.hn-dlg-seg--brass{stroke:var(--brass-400)}.hn-dlg-leg{display:flex;flex-direction:column;gap:6px;font-size:11px;color:var(--term-dim)}.hn-dlg-leg b{color:var(--term-fg)}.hn-dlg-leg i{display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:7px}.hn-dlg-leg i.hn-dlg-seg--wind{background:var(--wind-500)}.hn-dlg-leg i.hn-dlg-seg--leaf{background:var(--leaf-500)}.hn-dlg-leg i.hn-dlg-seg--amber{background:var(--amber-500)}.hn-dlg-leg i.hn-dlg-seg--brass{background:var(--brass-400)}.hn-dlg-donut-c{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.hn-dlg-donut-c b{font-family:var(--font-display);font-size:23px;color:var(--term-fg);line-height:1}.hn-dlg-donut-c span{font-size:9.5px;color:var(--term-dim);margin-top:2px}.hn-dlg-chart{display:block;width:100%;height:auto}.hn-dlg-chart line{stroke:var(--term-line);stroke-width:.6}.hn-dlg-chart text{font-family:var(--font-mono);font-size:7.5px;fill:var(--term-dim)}.hn-dlg-chart circle{fill:var(--wind-500)}.hn-dlg-trend{fill:none;stroke:var(--wind-500);stroke-width:1.6}.hn-dlg-foot{text-align:center;font-family:var(--font-mono);font-size:10px;letter-spacing:.28em;color:var(--brass-700);padding:12px 0 4px}@media (max-width: 1199px){.hn-dlg-grid{grid-template-columns:1fr}}@media (max-width: 767px){.hn-dlg-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}.hn-dlg-chips{display:none}.hn-dlg-hero-art{width:min(360px,100%)}}@media (max-width: 767px){.hn-dalang-head{flex-direction:column}.hn-dalang-stats{gap:16px}.hn-dalang-stat{text-align:left}.hn-dalang-stat>div:first-child{justify-content:flex-start}.hn-dalang-mascot{width:116px}.hn-dalang-blencong{display:none}.hn-dalang-live{width:100%}}/**
2
- * Copyright (c) 2014 The xterm.js authors. All rights reserved.
3
- * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
4
- * https://github.com/chjj/term.js
5
- * @license MIT
6
- *
7
- * Permission is hereby granted, free of charge, to any person obtaining a copy
8
- * of this software and associated documentation files (the "Software"), to deal
9
- * in the Software without restriction, including without limitation the rights
10
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- * copies of the Software, and to permit persons to whom the Software is
12
- * furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be included in
15
- * all copies or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- * THE SOFTWARE.
24
- *
25
- * Originally forked from (with the author's permission):
26
- * Fabrice Bellard's javascript vt100 for jslinux:
27
- * http://bellard.org/jslinux/
28
- * Copyright (c) 2011 Fabrice Bellard
29
- * The original design remains. The terminal itself
30
- * has been extended to include xterm CSI codes, among
31
- * other features.
32
- */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{font-family:monospace;-webkit-user-select:text;user-select:text;white-space:pre}.xterm .xterm-accessibility-tree>div{transform-origin:left;width:fit-content}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;background:#0000;transition:opacity .1s linear;z-index:11}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{position:absolute;display:none}.xterm .xterm-scrollable-element>.shadow.top{display:block;top:0;left:3px;height:3px;width:100%;box-shadow:var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.left{display:block;top:3px;left:0;height:100%;width:3px;box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.top-left-corner{display:block;top:0;left:0;height:3px;width:3px}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}