hanoman 0.3.1 → 0.3.2

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 (28) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/cli.js +415 -74
  3. package/dist/server.js +1848 -1108
  4. package/package.json +1 -1
  5. package/prisma/migrations/20260905120000_agent_evidence_identity/migration.sql +3 -0
  6. package/prisma/schema.prisma +2 -0
  7. package/web/assets/{ChangelogScreen-C3S2gIAp.js → ChangelogScreen-D_-RmJkz.js} +1 -1
  8. package/web/assets/{DalangHanomanScreen-Bf7WEGnw.js → DalangHanomanScreen-pVfnLx9z.js} +1 -1
  9. package/web/assets/{DocPreviewModal-DsAfvavy.js → DocPreviewModal-ZFjISCL0.js} +1 -1
  10. package/web/assets/{DocsWorkspace-BLRgm3tN.js → DocsWorkspace-Vp_vik3v.js} +1 -1
  11. package/web/assets/IdeScreen-DQSRs3fr.js +2 -0
  12. package/web/assets/{LeadScreen-Cko3FBrm.js → LeadScreen-Bv5LiudD.js} +1 -1
  13. package/web/assets/{ReviewScreen-5Kh6qQJn.js → ReviewScreen-Cime4Tci.js} +1 -1
  14. package/web/assets/SchedulerScreen-DKmRNbTs.js +1 -0
  15. package/web/assets/{SettingsScreen-D7LNmEUW.js → SettingsScreen-Bh8XhyVQ.js} +1 -1
  16. package/web/assets/{TeamScreen-VU3NfDdm.js → TeamScreen-5ugoXsOv.js} +1 -1
  17. package/web/assets/TerminalScreen-DsAn5dlH.js +9 -0
  18. package/web/assets/{TriageScreen-BxAGZi09.js → TriageScreen-BajACF5K.js} +1 -1
  19. package/web/assets/{VpsScreen-Xq65JDcT.js → VpsScreen-C7muNRX5.js} +1 -1
  20. package/web/assets/{diff-view-BNI0kLEC.js → diff-view-CsZPBznT.js} +1 -1
  21. package/web/assets/index-DI7G_sit.js +923 -0
  22. package/web/assets/live-DVDstDzi.js +1 -0
  23. package/web/index.html +1 -1
  24. package/web/assets/IdeScreen-CI0YYC3D.js +0 -2
  25. package/web/assets/SchedulerScreen-C4Qftb2o.js +0 -1
  26. package/web/assets/TerminalScreen-uPBkCPTD.js +0 -9
  27. package/web/assets/index-j_iWjqt5.js +0 -915
  28. package/web/assets/live-BkauBLCS.js +0 -1
@@ -1,9 +0,0 @@
1
- import{j as t,d as at,e as F,A as Xt,M as $e,S as me,G as Vt,J as zt,f as it,B as et,I as ve,w as Jt,D as Qt,a as ee,K as Zt,N as en,O as mt,Q as ht,c as Ye,U as tn,V as nn,W as rn,X as an,Y as sn,Z as on,_ as Me,$ as At,a0 as st,a1 as ln,h as De,a2 as Lt,a3 as cn,a4 as un,g as Xe,a5 as Nt,l as dn,x as pn,a6 as Ve,p as fn,a7 as mn,a8 as Be,a9 as hn,aa as gt,ab as gn,ac as xn}from"./index-j_iWjqt5.js";import{R as l,r as _}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import{D as bn,o as vn}from"./xterm-3VOAfa_q.js";function ot(e){return e.endedAt?e.endedReason==="reconciled"?"interrupted":e.exitCode===null||e.exitCode===0?"completed":"failed":"running"}const yn=new RegExp(["\\x1b\\[[?>][0-9;]*c","\\x1b\\[\\??[0-9]+;[0-9]+R","\\x1b\\[\\??[0-9;]*n","\\x1b\\[\\??[0-9;]*\\$y","\\x1b\\][0-9][0-9;]*;[^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)","\\x1bP[0-9]*[$+>][a-z|][^\\x1b]*\\x1b\\\\"].join("|"),"g"),kn=e=>e.length>0&&e.replace(yn,"")==="";function jn(e,n){if(e.type!=="keydown")return null;const a=e.key.toLowerCase();return e.metaKey||e.ctrlKey&&e.shiftKey?a==="c"?n?"copy":null:a==="v"?"paste":null:null}const wn=new Set(["image/png","image/jpeg","image/webp"]);function xt(e){return(e!=null&&e.files?Array.from(e.files):[]).filter(a=>wn.has(a.type))}function Sn(e){return e!=null&&e.types?Array.from(e.types).includes("Files"):!1}const Cn=96,In=50,En=2,Tn=2;function Rn(e,n,a){if(!Number.isFinite(e)||e<=0)return n;const i=a+En,s=Math.floor((e-Cn-In-Tn*i)/i);return s>=n?n:Math.max(0,s-1)}const zn=/enter to select/i,An=/to navigate/i,Ln=/^\s*[❯>*]?\s*(\d)\.\s/;function Nn(e,n){var s;const a=e.join(`
2
- `);if(!zn.test(a)||!An.test(a))return null;const i=e[n];return i?((s=Ln.exec(i))==null?void 0:s[1])??null:null}const Dt=10,Bt=24,lt=13,Dn=15;function tt(e){return Number.isFinite(e)?Math.min(Bt,Math.max(Dt,Math.round(e))):lt}const Bn=[{id:"esc",label:"Esc",seq:"\x1B",aria:"Kirim Escape ke terminal"},{id:"tab",label:"Tab",seq:" ",aria:"Kirim Tab ke terminal"},{id:"up",label:"↑",seq:"\x1B[A",aria:"Kirim panah atas ke terminal"},{id:"down",label:"↓",seq:"\x1B[B",aria:"Kirim panah bawah ke terminal"},{id:"left",label:"←",seq:"\x1B[D",aria:"Kirim panah kiri ke terminal"},{id:"right",label:"→",seq:"\x1B[C",aria:"Kirim panah kanan ke terminal"},{id:"enter",label:"Enter",seq:"\r",aria:"Kirim Enter ke terminal"}],$n=/[\x00-\x1f\x7f]/;function ct(e){return!e||$n.test(e)?"control":[...e].length>1?"bulk":"text"}function $t(e){return e?`\x1B[4m${e}\x1B[24m`:""}function Ge(e){return e>0?`\x1B[${e}D\x1B[K`:""}const Mn=500,Pn=5e3,Fn=64,On=2;function Mt(){return{pending:"",since:null,altScreen:!1,suspendedUntil:0,typed:"",unechoed:"",gen:0,parsed:0}}const Wn=e=>e.gen!==e.parsed;function _n(e,n){return{...e,altScreen:n}}const Kn=/(password|passphrase|pass|pin)\s*(?:for\s+\S+\s*)?:\s*$/i;function Hn(e){return Kn.test(e)}function Pt(e,n,a,i,s){return!s||!a.deliverable||e.altScreen||i<e.suspendedUntil||ct(n)!=="text"||a.cursorX+On+1>a.cols||a.line.slice(a.cursorX).trim().length>0?!1:!Hn(a.line.trimEnd())}function qn(e,n){for(let a=n.length;a>0;a-=1)if(e.endsWith(n.slice(0,a)))return a;return 0}function Gn(e,n,a,i,s){const d=ct(n);if(d==="text"&&Wn(e)&&s&&a.deliverable&&!e.altScreen&&i>=e.suspendedUntil)return e.unechoed.length>=Fn?{state:e,write:""}:{state:{...e,unechoed:e.unechoed+n,typed:""},write:"",deferred:!0};if(!Pt(e,n,a,i,s)){const h=i<e.suspendedUntil&&d==="text"?(e.typed+n).slice(-32):"";return h===e.typed&&!e.unechoed?{state:e,write:""}:{state:{...e,typed:h,unechoed:""},write:""}}return{state:{...e,pending:e.pending+n,unechoed:e.unechoed+n,since:null,typed:""},write:$t(n)}}function Un(e,n){if(!n)return!1;const a=n.slice(-Math.min(2,n.length));return e.endsWith(a)}function Yn(e,n,a){return a>=e.suspendedUntil?e.typed?{...e,typed:""}:e:Un(n,e.typed)?{...e,suspendedUntil:0,typed:""}:e}function Xn(e,n,a){return{state:{...e,pending:"",since:null,gen:e.gen+1},write:Ge(e.pending.length)+n}}function Vn(e,n,a,i,s){if(n!==e.gen)return{state:e,write:""};const d=a.line.slice(0,a.cursorX),v=Yn({...e,parsed:n},d,i);if(!v.unechoed)return{state:v,write:""};const h=v.unechoed.slice(qn(d,v.unechoed));if(!h)return{state:{...v,unechoed:""},write:""};const I=Qn({...v,pending:""},h,a,i,s);return I.write?{state:{...I.state,unechoed:h},write:I.write}:{state:{...v,pending:"",unechoed:""},write:""}}function Jn(e,n){return!e.pending||e.since!==null?e:{...e,since:n}}function Qn(e,n,a,i,s){if(!n)return{state:e,write:""};const d=[...n];for(let v=0;v<d.length;v+=1){const h={...a,cursorX:a.cursorX+v};if(!Pt({...e},d[v],h,i,s))return{state:e,write:""}}return{state:{...e,pending:n,since:null},write:$t(n)}}function Zn(e,n){return!e.pending||e.since===null||n<e.since+Mn?{state:e,write:"",missed:!1}:{state:{...e,pending:"",since:null,suspendedUntil:n+Pn,typed:"",unechoed:""},write:Ge(e.pending.length),missed:!0}}function bt(e){const n=((e==null?void 0:e.gen)??0)+1;return{...Mt(),gen:n,parsed:n}}const er=16;function tr(e){let n="",a;const i=()=>{if(a&&(clearTimeout(a),a=void 0),!n)return;const s=n;n="",e(s)};return{push(s,d){if(!d||ct(s)!=="text"){i(),s&&e(s);return}n+=s,a||(a=setTimeout(i,er))},flush:i,dispose(){i()}}}const nr=250,rr=512,ar={"\x1B":"\\e","\r":"\\r","\n":"\\n"," ":"\\t","\b":"\\b","":"\\x7f"};function vt(e){let n="";for(const a of e){const i=ar[a];if(i){n+=i;continue}const s=a.codePointAt(0);n+=s<32||s===127?`\\x${s.toString(16).padStart(2,"0")}`:a}return n}function ir(e){const n=e.batchMs??nr,a=e.max??rr;let i=null,s=[],d,v=!1;const h=()=>{if(d&&(clearTimeout(d),d=void 0),!s.length)return;const I=s;s=[],e.send(I)};return{record(I,T,g){if(v)return;const b=e.now();i===null&&(i=b);const N={t:b-i,k:I,v:T};g!==void 0&&(N.n=g),s.push(N),s.length>a&&(s=s.slice(s.length-a)),d||(d=setTimeout(h,n))},flush:h,dispose(){h(),v=!0}}}const sr="",or=350,lr=1e3;function ut(){return{text:"",sentPrefix:""}}function cr(e,n){const a=[...e],i=[...n];let s=0;for(;s<a.length&&s<i.length&&a[s]===i[s];)s+=1;return s}function dt(e,n){const a=cr(e,n);return sr.repeat([...e].length-a)+[...n].slice(a).join("")}function ur(e,n){return{...e,text:n}}function dr(e){return{state:{...e,sentPrefix:e.text},send:dt(e.sentPrefix,e.text)}}function pr(e){return{state:ut(),send:dt(e.sentPrefix,e.text)+"\r"}}function fr(e){return{state:ut(),send:dt(e.sentPrefix,e.text)}}function mr(e,n){return n.held?{kind:"held",text:"tertahan — Kirim di atas"}:n.n>0?{kind:"queued",text:`diantre ${n.n}`}:e==="open"?{kind:"sent",text:"terkirim"}:null}function hr({sessionId:e,send:n,external:a,linkState:i,queue:s}){const[d,v]=l.useState(""),h=l.useRef(ut()),I=l.useRef(n);I.current=n;const T=l.useRef(void 0),g=l.useRef(void 0),b=()=>{clearTimeout(T.current),T.current=void 0,clearTimeout(g.current),g.current=void 0},N=C=>{b(),h.current=C.state,C.send&&I.current(C.send)},z=()=>N(dr(h.current));a.current=()=>{N(fr(h.current)),v("")},l.useEffect(()=>()=>{a.current=()=>{}},[a]),l.useEffect(()=>b,[]);const E=C=>{h.current=ur(h.current,C),v(C),clearTimeout(T.current),T.current=setTimeout(z,or),g.current||(g.current=setTimeout(z,lr))},j=()=>{N(pr(h.current)),v("")},f=mr(i,s);return t.jsxs("div",{className:"hn-terminal-composer",children:[t.jsx(at,{size:"lg",mono:!0,value:d,"data-testid":"terminal-composer","aria-label":`Ketik untuk sesi ${e}`,placeholder:"mis. pnpm vitest --run",autoCapitalize:"off",autoCorrect:"off",spellCheck:!1,autoComplete:"off",enterKeyHint:"send",style:{flex:"1 1 160px",minWidth:0},onChange:C=>E(C.target.value),onBlur:()=>z(),onKeyDown:C=>{C.key!=="Enter"||C.nativeEvent.isComposing||(C.preventDefault(),j())}}),f&&t.jsx("span",{"data-testid":"terminal-composer-status",className:`hn-terminal-composer-status hn-terminal-composer-status--${f.kind}`,children:f.text})]})}const Ft=[500,1e3,2e3,4e3,8e3,8e3,8e3,8e3,8e3,8e3,8e3,8e3],yt=Ft.length,gr=4096,xr=/[\r\n]/;function Ot({sessionId:e,onExit:n,onPhases:a,fontSize:i=lt,showKeys:s=!1,predict:d=!0,diag:v=!1}){const h=l.useRef(null),I=l.useRef(i);I.current=i;const T=l.useRef(d);T.current=d;const g=l.useRef(v);g.current=v;const b=l.useRef(null),N=l.useRef(n);N.current=n;const z=l.useRef(a);z.current=a;const[E,j]=l.useState({state:"connecting"}),[f,C]=l.useState({n:0,held:!1,full:!1}),S=l.useRef(()=>{}),k=l.useRef(()=>{}),M=l.useRef(()=>{}),w=l.useRef(()=>{}),D=l.useRef(()=>{}),p=l.useRef(()=>{});return l.useEffect(()=>{const c=h.current;if(!c)return;const L=getComputedStyle(document.documentElement),B=(u,r)=>L.getPropertyValue(u).trim()||r,x=new bn({fontFamily:B("--font-mono","monospace"),fontSize:tt(I.current),cursorBlink:!0,macOptionClickForcesSelection:!0,theme:{background:B("--term-bg","#1c1810"),foreground:B("--term-fg","#e9e0cd")}}),H=new vn;x.loadAddon(H),x.open(c);const q=()=>{const u=c.getBoundingClientRect();return u.width>0&&u.height>0?u:null};q()&&H.fit();let A,G=!1,te=0,ne,U=!1;const le=u=>{(A==null?void 0:A.readyState)===WebSocket.OPEN&&A.send(JSON.stringify(u))};b.current={term:x,fit:H,send:le};const V=ir({now:()=>Date.now(),send:u=>le({t:"diag",ev:u})}),J=(u,r,o)=>{g.current&&V.record(u,r,o)};let Y="",X=!1,Q=!1,re=0,ce=0,he=!1;const ue=new Map,O=u=>{if(re+=1,ce+=1,g.current){if(ue.size>256)for(const r of[...ue.keys()].slice(0,128))ue.delete(r);ue.set(re,Date.now())}le({t:"in",d:u,seq:re})},W=()=>C({n:Y.length,held:X,full:Q}),K=u=>{if(!X&&!Y&&(A==null?void 0:A.readyState)===WebSocket.OPEN){O(u);return}if(!(he||kn(u))){if(Y.length+u.length>gr){Q=!0,W();return}Y+=u,W()}};let R=Mt();const ae=tr(K),ie=u=>ae.push(u,!1);k.current=ie;const se=u=>{D.current(),ie(u)};p.current=se;const we=()=>{var r;const u=x.buffer.active;return{cursorX:u.cursorX,cols:x.cols,deliverable:!he&&!Q,line:((r=u.getLine(u.viewportY+u.cursorY))==null?void 0:r.translateToString(!0))??""}},ge=()=>{ce===0&&(A==null?void 0:A.readyState)===WebSocket.OPEN&&(R=Jn(R,Date.now()))},Fe=()=>{if(!Y||(A==null?void 0:A.readyState)!==WebSocket.OPEN){W();return}const u=Y;Y="",Q=!1,W(),O(u)},Re=()=>{if(ae.flush(),!Y){W();return}if(xr.test(Y)){X=!0,W();return}Fe()};M.current=()=>{X=!1,Fe()},w.current=()=>{Y="",X=!1,Q=!1,W()};const Se=u=>{D.current();const r=R.pending.length>0;J("data",vt(u));const o=we(),m=Gn(R,u,o,Date.now(),T.current);R=m.state,m.write?x.write(m.write):m.deferred?J("pred","tangguh: frame server in flight"):J("pred",`tolak cx=${o.cursorX}/${o.cols} alt=${R.altScreen?1:0} deliverable=${o.deliverable?1:0} suspend=${Math.max(0,R.suspendedUntil-Date.now())}`),ae.push(u,r||m.write.length>0||m.deferred===!0)},ye=setInterval(()=>{const u=Zn(R,Date.now());R=u.state,u.write&&x.write(u.write)},100),ze=()=>{F.issueWsTicket(`terminal:${e}`).then(({ticket:u})=>{if(G)return;const r=location.protocol==="https:"?"wss:":"ws:",o=new WebSocket(`${r}//${location.host}${Xt.terminalWs(e)}`,[`hanoman-ticket.${u}`]);A=o,o.onopen=()=>{te=0,re=0,ce=0;const m=Ge(R.pending.length);m&&x.write(m),R=bt(R),j({state:"open"}),q()&&((typeof window.matchMedia!="function"||window.matchMedia("(hover: hover) and (pointer: fine)").matches)&&x.focus(),le({t:"resize",cols:x.cols,rows:x.rows})),Re()},o.onmessage=m=>{var Z;const y=JSON.parse(m.data);if(y.t==="data"){const de=Xn(R,y.d??"");R=de.state;const oe=R.gen;x.write(de.write,()=>{if(G)return;const fe=Vn(R,oe,we(),Date.now(),T.current);R=fe.state,fe.write&&x.write(fe.write),ge()}),ge()}else if(y.t==="ack"){if(ce=Math.max(0,ce-1),typeof y.seq=="number"){const de=ue.get(y.seq);de!==void 0&&(ue.delete(y.seq),J("ack",String(y.seq),Date.now()-de))}ge()}else y.t==="phase"?(Z=z.current)==null||Z.call(z,y.phases??[],y.complete===!0):y.t==="alt"?R=_n(R,y.on===!0):y.t==="exit"&&(U=!0,x.write(`\r
3
- \x1B[33m— sesi berakhir (exit ${y.code}) —\x1B[0m\r
4
- `),N.current(y.code??0))},o.onclose=m=>{if(!(G||U)){if(m.code===4004){he=!0;const y=Ge(R.pending.length);y&&x.write(y),R=bt(R),Y="",X=!1,Q=!1,W(),j({state:"gone"});return}Ae()}},o.onerror=()=>{}}).catch(()=>{G||(x.write(`\r
5
- \x1B[31mWebSocket admission gagal\x1B[0m\r
6
- `),Ae())})},Ae=()=>{if(te>=yt){j({state:"lost"});return}const u=Ft[te];te+=1,j({state:"retrying",attempt:te}),ne=setTimeout(ze,u)};S.current=()=>{G||(clearTimeout(ne),te=0,j({state:"retrying",attempt:1}),ze())},ze(),x.attachCustomKeyEventHandler(u=>{var o,m;const r=jn(u,x.hasSelection());return r==="copy"?((o=navigator.clipboard)==null||o.writeText(x.getSelection()),!1):r==="paste"?((m=navigator.clipboard)==null||m.readText().then(y=>{y&&se(y)}),!1):!0}),x.attachCustomWheelEventHandler(u=>{if(!u.shiftKey)return!0;const r=q();if(!r||x.rows<=0)return!0;const o=r.height/x.rows,m=Math.trunc(u.deltaY/o)||Math.sign(u.deltaY);return m&&x.scrollLines(m),!1});const Ue=x.onData(Se),$=x.textarea,Le=u=>J("key",u.key,u.keyCode),xe=u=>J("comp",`${u.type}:${vt(u.data??"")}`);$==null||$.addEventListener("keydown",Le),$==null||$.addEventListener("compositionstart",xe),$==null||$.addEventListener("compositionupdate",xe),$==null||$.addEventListener("compositionend",xe);let pe=null,ke=0,Ce=!1;const je=()=>{pe=null,ke=0,Ce=!1},Oe=u=>{if(u.touches.length!==1){je();return}pe=u.touches[0].clientY,ke=0,Ce=!1},We=u=>{if(pe===null||u.touches.length!==1){je();return}const r=q();if(!r||x.rows<=0)return;const o=u.touches[0].clientY;ke+=pe-o,pe=o;const m=r.height/x.rows,y=Math.trunc(ke/m);y!==0&&(x.scrollLines(y),ke-=y*m,Ce=!0),u.preventDefault()},Ie=u=>{var fe,pt;const r=pe!==null&&!Ce,o=((pt=(fe=u.changedTouches)==null?void 0:fe[0])==null?void 0:pt.clientY)??pe;if(je(),!r||o===null||o===void 0)return;const m=q();if(!m||x.rows<=0)return;const y=Math.floor((o-m.top)/(m.height/x.rows)),Z=x.buffer.active,de=Array.from({length:x.rows},(Kr,Yt)=>{var ft;return((ft=Z.getLine(Z.viewportY+Yt))==null?void 0:ft.translateToString(!0))??""}),oe=Nn(de,y);oe&&se(oe)},P=async u=>{for(const r of u)try{const{path:o}=await F.uploadTerminalAttachment(e,r);se(`${o} `)}catch(o){x.write(`\r
7
- \x1B[31mlampiran gagal: ${o.message}\x1B[0m\r
8
- `)}},Ne=u=>{const r=xt(u.clipboardData);r.length&&(u.preventDefault(),P(r))},_e=u=>{Sn(u.dataTransfer)&&u.preventDefault()},Ke=u=>{const r=xt(u.dataTransfer);r.length&&(u.preventDefault(),P(r))};c.addEventListener("paste",Ne),c.addEventListener("dragover",_e),c.addEventListener("drop",Ke),c.addEventListener("touchstart",Oe,{passive:!0}),c.addEventListener("touchmove",We,{passive:!1}),c.addEventListener("touchend",Ie,{passive:!0}),c.addEventListener("touchcancel",je,{passive:!0});const He=new ResizeObserver(u=>{var o;const r=((o=u[0])==null?void 0:o.contentRect)??c.getBoundingClientRect();r.width<=0||r.height<=0||(H.fit(),le({t:"resize",cols:x.cols,rows:x.rows}))});return He.observe(c),()=>{G=!0,clearTimeout(ne),S.current=()=>{},k.current=()=>{},p.current=()=>{},M.current=()=>{},w.current=()=>{},b.current=null,c.removeEventListener("paste",Ne),c.removeEventListener("dragover",_e),c.removeEventListener("drop",Ke),c.removeEventListener("touchstart",Oe),c.removeEventListener("touchmove",We),c.removeEventListener("touchend",Ie),c.removeEventListener("touchcancel",je),He.disconnect(),clearInterval(ye),ae.dispose(),V.dispose(),$==null||$.removeEventListener("keydown",Le),$==null||$.removeEventListener("compositionstart",xe),$==null||$.removeEventListener("compositionupdate",xe),$==null||$.removeEventListener("compositionend",xe),Ue.dispose(),A==null||A.close(),x.dispose()}},[e]),l.useEffect(()=>{const c=b.current,L=h.current;if(!c||!L)return;const B=tt(i);if(c.term.options.fontSize===B)return;c.term.options.fontSize=B;const x=L.getBoundingClientRect();x.width<=0||x.height<=0||(c.fit.fit(),c.send({t:"resize",cols:c.term.cols,rows:c.term.rows}))},[i]),l.useEffect(()=>{const c=b.current,L=h.current;if(!c||!L)return;const B=L.getBoundingClientRect();B.width<=0||B.height<=0||(c.fit.fit(),c.send({t:"resize",cols:c.term.cols,rows:c.term.rows}))},[s]),t.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},children:[(E.state!=="open"&&E.state!=="connecting"||f.held||f.full)&&t.jsxs("div",{"data-testid":"terminal-link",style:{display:"flex",alignItems:"center",gap:8,flex:"0 0 auto",flexWrap:"wrap",padding:"3px 8px",fontFamily:"var(--font-mono)",fontSize:11,background:E.state==="retrying"||f.held?"var(--status-warn-tint)":"var(--status-err-tint)",color:"var(--text-body)"},children:[E.state==="retrying"&&t.jsxs("span",{children:["menyambung ulang… (",E.attempt,"/",yt,")"]}),E.state==="gone"&&t.jsx("span",{children:"sesi tidak ditemukan di tmux"}),E.state==="lost"&&t.jsxs(t.Fragment,{children:[t.jsx("span",{children:"terputus"}),t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>S.current(),children:"Sambungkan lagi"})]}),f.n>0&&!f.held&&t.jsxs("span",{"data-testid":"terminal-queue",children:[f.n," ketikan diantre"]}),f.held&&t.jsxs(t.Fragment,{children:[t.jsxs("span",{"data-testid":"terminal-held",children:[f.n," ketikan tertahan — belum dikirim"]}),t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>M.current(),children:"Kirim"}),t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>w.current(),children:"Buang"})]}),f.full&&t.jsx("span",{"data-testid":"terminal-queue-full",children:"antrean penuh"})]}),t.jsx("div",{ref:h,"data-testid":"terminal-host",style:{flex:1,minHeight:0,width:"100%",background:"var(--term-bg)",padding:8,borderRadius:"var(--radius-sm)",touchAction:"pan-x pinch-zoom",overscrollBehavior:"contain"}}),s&&t.jsx(hr,{sessionId:e,send:c=>k.current(c),external:D,linkState:E.state,queue:f}),s&&t.jsx(br,{onKey:c=>p.current(c)})]})}function br({onKey:e}){return t.jsx("div",{className:"hn-terminal-keys",role:"group","aria-label":"Tombol terminal",children:Bn.map(n=>t.jsx("button",{type:"button",className:"hn-terminal-key","aria-label":n.aria,title:n.aria,onClick:()=>e(n.seq),children:n.label},n.id))})}const kt=20;function vr(e,n){if(!n)return"—";const a=new Date(n).getTime()-new Date(e).getTime();if(!Number.isFinite(a)||a<0)return"—";const i=Math.round(a/1e3);if(i<60)return`${i} dtk`;const s=Math.round(i/60);return s<60?`${s} mnt`:`${Math.floor(s/60)} jam ${s%60} mnt`}function yr(e){switch(ot(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 Wt=e=>ot(e)==="interrupted"?"—":vr(e.startedAt,e.endedAt),_t=e=>zt[e]??e;function kr({projects:e,onClose:n,onRestart:a}){const[i,s]=l.useState([]),[d,v]=l.useState(0),[h,I]=l.useState(1),[T,g]=l.useState(!1),[b,N]=l.useState(""),[z,E]=l.useState(""),[j,f]=l.useState(""),[C,S]=l.useState(""),[k,M]=l.useState(null);l.useEffect(()=>{const p=setTimeout(()=>S(j.trim()),250);return()=>clearTimeout(p)},[j]),l.useEffect(()=>{I(1)},[b,z,C]),l.useEffect(()=>{let p=!0;return g(!0),F.listSessionHistory({projectId:b||void 0,kind:z||void 0,q:C||void 0,page:h,limit:kt}).then(c=>{p&&(v(c.total),s(c.items))}).catch(()=>{p&&(s([]),v(0))}).finally(()=>{p&&g(!1)}),()=>{p=!1}},[b,z,C,h]);const w=Qt(d,h,kt),D=p=>{var c;return((c=e.find(L=>L.id===p))==null?void 0:c.name)??p};return t.jsxs($e,{open:!0,title:"Riwayat sesi",icon:"history",onClose:n,width:900,children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",marginBottom:10},children:[t.jsx(at,{size:"sm",leftIcon:"search",placeholder:"mis. spec-412 atau reverse","aria-label":"Cari riwayat sesi",value:j,onChange:p=>f(p.target.value),style:{flex:"1 1 200px"}}),t.jsx(me,{size:"sm","aria-label":"Filter project",value:b,onChange:p=>N(p.target.value),options:[{value:"",label:"Semua project"}].concat(e.map(p=>({value:p.id,label:p.name})))}),t.jsx(me,{size:"sm","aria-label":"Filter jenis",value:z,onChange:p=>E(p.target.value),options:[{value:"",label:"Semua jenis"}].concat(Vt.map(p=>({value:p,label:zt[p]})))})]}),i.length===0&&!T?t.jsx(it,{kind:"empty",icon:"history",title:"Belum ada riwayat sesi",hint:"Riwayat terisi sendiri saat sesi terminal dibuka lalu ditutup — termasuk sesi backlog, terminal biasa, dan sesi project-level."}):t.jsxs("div",{style:{display:"flex",flexDirection:"column",maxHeight:"60vh",overflowY:"auto"},children:[i.map(p=>{const c=yr(p);return t.jsx("button",{onClick:()=>M(p),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:t.jsxs("span",{className:"hn-dense-row hn-picker-row",style:{display:"flex",alignItems:"center",gap:10,width:"100%"},children:[t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",flex:"0 0 132px"},children:new Date(p.startedAt).toLocaleString("id-ID")}),t.jsx(et,{size:"sm",tone:"neutral",children:_t(p.kind)}),t.jsx("span",{className:"hn-picker-title",style:{flex:1,minWidth:0,fontSize:13,color:"var(--text-strong)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:p.title??p.specId??D(p.projectId)}),p.transcriptBytes!==null&&t.jsx(ve,{name:"file-text",size:12,color:"var(--text-subtle)"}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-muted)",flex:"0 0 72px"},children:Wt(p)}),t.jsx(et,{size:"sm",tone:c.tone,children:c.label})]})},p.id)}),T&&t.jsx("div",{style:{padding:"10px 8px",textAlign:"center",fontSize:11,color:"var(--text-subtle)"},children:"memuat…"})]}),t.jsx(Jt,{page:w.page,pageCount:w.pageCount,total:d,from:w.from,to:w.to,onPage:I,unit:"sesi"}),k&&t.jsx(jr,{row:k,projectName:D(k.projectId),onBack:()=>M(null),onRestart:a})]})}function jr({row:e,projectName:n,onBack:a,onRestart:i}){const[s,d]=l.useState(null),[v,h]=l.useState("idle");l.useEffect(()=>{if(e.transcriptBytes===null){h("none"),d(null);return}let g=!0;return h("loading"),F.sessionTranscript(e.id).then(b=>{g&&(d(b.text),h("idle"))}).catch(()=>{g&&(d(null),h("error"))}),()=>{g=!1}},[e.id,e.transcriptBytes]);const I=ot(e)==="interrupted",T=[["Project",n],["Sesi",e.sessionId],["Jenis",_t(e.kind)],["Agen",[e.agent,e.model,e.effort].filter(Boolean).join(" · ")],["Mulai",new Date(e.startedAt).toLocaleString("id-ID")],[I?"Terakhir terlihat hidup":"Selesai",e.endedAt?new Date(e.endedAt).toLocaleString("id-ID"):"berjalan"],...I&&e.reconciledAt?[["Terdeteksi mati",new Date(e.reconciledAt).toLocaleString("id-ID")]]:[],["Durasi",Wt(e)],["Direktori",e.cwd]];return e.specId&&T.splice(1,0,["Backlog",`${e.specId}${e.title?` · ${e.title}`:""}`]),e.branch&&T.push(["Branch",e.branch]),t.jsxs($e,{open:!0,title:e.title??e.specId??e.sessionId,icon:"history",onClose:a,width:1e3,children:[t.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",marginBottom:10},children:[t.jsx(ee,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:a,children:"Kembali"}),t.jsx("div",{style:{flex:1}}),s&&t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"copy",onClick:()=>{var g;return void((g=navigator.clipboard)==null?void 0:g.writeText(s))},children:"Salin transkrip"}),Zt(e.kind)&&t.jsx(ee,{size:"sm",leftIcon:"play",onClick:()=>i(e),children:"Mulai lagi"})]}),I&&t.jsxs(en,{tone:"warn",title:"Sesi terputus — hasilnya tak diketahui",style:{marginBottom:12},children:["Panenya sudah lenyap saat hanoman menyala lagi (reboot, ",t.jsx("code",{children:"tmux kill-server"}),", atau host mati), jadi sesi ini tak meninggalkan exit code dan transkripnya kemungkinan besar tak sempat diambil — capture berjalan tepat sebelum pane dibunuh, dan di jalur ini sudah tak ada pane untuk dibaca. Periksa worktree & branch sesi ini sebelum menganggapnya selesai, lalu mulai lagi bila pekerjaannya belum tuntas."]}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"4px 12px",marginBottom:12,fontSize:12},children:T.map(([g,b])=>t.jsxs(l.Fragment,{children:[t.jsx("span",{style:{color:"var(--text-subtle)"},children:g}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",color:"var(--text-body)",wordBreak:"break-all"},children:b})]},g))}),v==="loading"&&t.jsx("div",{style:{fontSize:12,color:"var(--text-subtle)"},children:"memuat transkrip…"}),v==="none"&&t.jsx("div",{style:{fontSize:12,color:"var(--text-subtle)"},children:I?"Tanpa transkrip — panenya sudah lenyap sebelum hanoman sempat mengambilnya.":"Tanpa transkrip — sesi ini ditutup sebelum fitur riwayat ada, atau panenya tak menyisakan keluaran."}),v==="error"&&t.jsx("div",{style:{fontSize:12,color:"var(--clay-600)"},children:"Transkrip tak terbaca lagi di server."}),s!==null&&t.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:s})]})}function wr({open:e,projectId:n,projectName:a,onClose:i,onCreated:s}){var M;const[d,v]=l.useState("claude"),[h,I]=l.useState("claude-opus-5"),[T,g]=l.useState("xhigh"),[b,N]=l.useState({claude:{model:"claude-opus-5",effort:"xhigh"},codex:{...mt}}),[z,E]=l.useState(!1),[j,f]=l.useState(null);l.useEffect(()=>{e&&(F.getSettings().then(w=>{const D={claude:{model:w.model,effort:w.effort},codex:{...mt,...w.codex??{}}},p=w.agent==="codex"?"codex":"claude",c=ht(D,p);N(D),v(p),I(c.model),g(c.effort)}).catch(()=>{}),F.getCodexVersion().then(w=>f(w.version)).catch(()=>{}))},[e]);const C=w=>{v(w);const D=ht(b,w);I(D.model),g(D.effort)},S=w=>{I(w),g(D=>d==="codex"?sn(w,D):on(w,D))};async function k(){E(!0);try{const{id:w}=await F.createTerminal(n,{agent:d,model:h,effort:T});s(w),i()}catch{}finally{E(!1)}}return t.jsxs($e,{open:e,onClose:i,icon:"plus",eyebrow:a,title:"Sesi baru",footer:t.jsxs(t.Fragment,{children:[t.jsx(ee,{variant:"ghost",onClick:i,children:"Batal"}),t.jsx(ee,{leftIcon:"play",disabled:z,onClick:()=>void k(),children:"Buka sesi"})]}),children:[t.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 — ",t.jsx("code",{children:"/model"})," di terminal tetap bisa mengubahnya."]}),t.jsx(Ye,{label:"Agen",hint:"Mesin yang menjalankan sesi ini. Perilaku sesi sama; hanya CLI-nya berbeda.",children:t.jsx(me,{"aria-label":"Agen",value:d,style:{width:"100%"},options:[{value:"claude",label:"Claude Code"},{value:"codex",label:"Codex CLI"}],onChange:w=>C(w.target.value)})}),t.jsx(Ye,{label:"Model",children:t.jsx(me,{"aria-label":"Model",value:h,style:{width:"100%"},options:tn(d).map(w=>({value:w.id,label:w.label})),onChange:w=>S(w.target.value)})}),t.jsx(Ye,{label:"Effort",children:t.jsx(me,{"aria-label":"Effort",value:T,style:{width:"100%"},options:nn(d,h).map(w=>({value:w,label:w})),onChange:w=>g(w.target.value)})}),d==="codex"&&rn(h,j)&&t.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 ",t.jsx("b",{children:j}),", sedangkan ",t.jsx("b",{children:h})," butuh ",t.jsx("b",{children:(M=an(h))==null?void 0:M.minClient}),". Sesi tetap boleh dijalankan, tapi modelnya belum tentu dikenali CLI ini."]})]})}const Sr=()=>({rows:1,cols:1,cells:[null]}),jt=e=>({...e,rows:e.rows+1,cells:[...e.cells,...Array(e.cols).fill(null)]});function wt(e){const n=e.cols+1,a=[];for(let i=0;i<e.rows;i++)for(let s=0;s<n;s++)a.push(s<e.cols?e.cells[i*e.cols+s]??null:null);return{rows:e.rows,cols:n,cells:a}}function St(e,n){if(e.rows===1||n<0||n>=e.rows)return e;const a=[...e.cells];return a.splice(n*e.cols,e.cols),{...e,rows:e.rows-1,cells:a}}function Ct(e,n){if(e.cols===1||n<0||n>=e.cols)return e;const a=e.cols-1,i=[];for(let s=0;s<e.rows;s++)for(let d=0;d<e.cols;d++)d!==n&&i.push(e.cells[s*e.cols+d]??null);return{rows:e.rows,cols:a,cells:i}}function nt(e,n,a){if(n<0||n>=e.cells.length)return e;const i=e.cells.map(s=>a!==null&&s===a?null:s);return i[n]=a,{...e,cells:i}}const Cr=(e,n)=>({...e,cells:e.cells.map(a=>a&&n.has(a)?a:null)}),Kt=e=>({id:crypto.randomUUID(),name:e,layout:Sr()});function It(){const e=Kt("Utama");return{groups:[e],active:e.id}}const Pe=e=>e.groups.find(n=>n.id===e.active)??e.groups[0];function Ir(e,n){const a=Kt(n);return{groups:[...e.groups,a],active:a.id}}const Er=(e,n,a)=>({...e,groups:e.groups.map(i=>i.id===n?{...i,name:a}:i)});function Tr(e,n){if(e.groups.length===1)return e;const a=e.groups.filter(i=>i.id!==n);return a.length===e.groups.length?e:{groups:a,active:e.active===n?a[0].id:e.active}}const Rr=(e,n)=>e.groups.some(a=>a.id===n)?{...e,active:n}:e;function be(e,n){const a=Pe(e);return{...e,groups:e.groups.map(i=>i.id===a.id?{...i,layout:n(i.layout)}:i)}}function rt(e,n,a){const i=Pe(e),s=a===null?e.groups:e.groups.map(d=>d.id===i.id?d:{...d,layout:nt(d.layout,d.layout.cells.indexOf(a),null)});return{...e,groups:s.map(d=>d.id===i.id?{...d,layout:nt(d.layout,n,a)}:d)}}function Ee(e,n){const a=Pe(e).layout.cells.indexOf(null);return a===-1?e:rt(e,a,n)}const zr=(e,n)=>({...e,groups:e.groups.map(a=>({...a,layout:nt(a.layout,a.layout.cells.indexOf(n),null)}))}),Et=e=>new Set(e.groups.flatMap(n=>n.layout.cells.filter(a=>a!==null))),Tt=(e,n)=>({...e,groups:e.groups.map(a=>({...a,layout:Cr(a.layout,n)}))}),Ht="hanoman.terminal.workspace",qt="hanoman.terminal.layout",Te=e=>Me.parse({version:1,groups:e.groups});function qe(e,n){const a=e.groups,i=n&&a.some(s=>s.id===n)?n:a[0].id;return{groups:a,active:i}}function Ar(e){try{const n=JSON.parse(e);if(!n||typeof n!="object")return null;const a=n,i=Me.parse({version:1,groups:a.groups});return{workspace:i,active:typeof a.active=="string"&&i.groups.some(s=>s.id===a.active)?a.active:i.groups[0].id}}catch{return null}}function Lr(){try{const e=localStorage.getItem(Ht);if(e)return Ar(e);const n=localStorage.getItem(qt);if(!n)return null;const a=JSON.parse(n),i={id:crypto.randomUUID(),name:"Utama",layout:a};return{workspace:Me.parse({version:1,groups:[i]}),active:i.id}}catch{return null}}function Je(){try{localStorage.removeItem(Ht),localStorage.removeItem(qt)}catch{}}const Gt=e=>`hanoman.terminal.workspace.v2.${encodeURIComponent(e)}`;function Nr(e){try{const n=localStorage.getItem(Gt(e));if(!n)return null;const a=JSON.parse(n),i=Me.parse(a.workspace);if(!Number.isInteger(a.revision)||(a.revision??-1)<0)return null;const s=typeof a.active=="string"&&i.groups.some(d=>d.id===a.active)?a.active:i.groups[0].id;return{workspace:i,revision:a.revision,active:s}}catch{return null}}function Qe(e,n){try{const a=Me.parse(n.workspace);if(!Number.isInteger(n.revision)||n.revision<0)return;const i=a.groups.some(s=>s.id===n.active)?n.active:a.groups[0].id;localStorage.setItem(Gt(e),JSON.stringify({workspace:a,revision:n.revision,active:i}))}catch{}}function Ze(e){if(!(e instanceof st)||e.status!==409)return null;const n=e.detail;if((n==null?void 0:n.code)!=="revision-conflict")return null;const a=ln.safeParse(n.current);return a.success?a.data:null}function Dr(e){const n=_.useRef(null);n.current||(n.current=It());const[a,i]=_.useState(n.current),[s,d]=_.useState("loading"),[v,h]=_.useState(null),[I,T]=_.useState(!1),g=_.useRef(a),b=_.useRef(0),N=_.useRef(!1),z=_.useRef(Promise.resolve()),E=_.useRef(0),j=_.useCallback(p=>{g.current=p,i(p)},[]),f=_.useCallback(p=>{N.current=p,T(p)},[]),C=_.useCallback(p=>{const c=z.current.then(p,p);return z.current=c.then(()=>{},()=>{}),c},[]),S=_.useCallback((p,c="ready",L=null,B=g.current.active)=>{const x=p.workspace?qe(p.workspace,B):It();b.current=p.revision,j(x),d(c),h(L),f(!0),p.workspace&&Qe(e,{workspace:p.workspace,revision:p.revision,active:x.active})},[j,f,e]),k=_.useCallback(p=>{const c=Nr(e);c&&(b.current=c.revision,j(qe(c.workspace,c.active))),f(!1),d("recovering"),h(p instanceof Error?p.message:"Layout server belum tersambung")},[j,f,e]),M=_.useCallback(()=>C(async()=>{try{S(await F.getTerminalWorkspace())}catch(p){k(p)}}),[S,C,k]);_.useEffect(()=>{const p=++E.current;return d("loading"),h(null),f(!1),C(async()=>{try{const c=await F.getTerminalWorkspace();if(p!==E.current)return;if(c.workspace){S(c),Je();return}const L=Lr();if(!L){S(c);return}try{const B=await F.putTerminalWorkspace({baseRevision:c.revision,workspace:L.workspace});if(p!==E.current)return;j(qe(B.workspace,L.active)),b.current=B.revision,Qe(e,{workspace:B.workspace,revision:B.revision,active:L.active}),Je(),d("ready"),h(null),f(!0)}catch(B){const x=Ze(B);x!=null&&x.workspace?(S(x,"conflict","Layout server lebih baru; layout lokal lama tidak diunggah"),Je()):k(B)}}catch(c){p===E.current&&k(c)}}),()=>{E.current+=1}},[S,C,k,j,f,e]),_.useEffect(()=>{const p=()=>{M()},c=()=>{document.visibilityState==="visible"&&M()};return window.addEventListener("focus",p),document.addEventListener("visibilitychange",c),()=>{window.removeEventListener("focus",p),document.removeEventListener("visibilitychange",c)}},[M]);const w=_.useCallback(p=>C(async()=>{if(!N.current)return!1;const c=p(g.current);let L,B;try{L=Te(c),B=Te(g.current)}catch{return d("conflict"),h("Layout tidak valid dan tidak disimpan"),!1}if(At(L,B))return!0;try{return S(await F.putTerminalWorkspace({baseRevision:b.current,workspace:L}),"ready",null,c.active),!0}catch(x){const H=Ze(x);if(!(H!=null&&H.workspace))return k(x),!1;const q=p(qe(H.workspace,g.current.active));try{const A=await F.putTerminalWorkspace({baseRevision:H.revision,workspace:Te(q)});return S(A,"conflict","Layout berubah di perangkat lain; perubahan ini diterapkan ulang",q.active),!0}catch(A){if(!Ze(A)&&!(A instanceof st&&A.status===409))return k(A),!1;try{S(await F.getTerminalWorkspace(),"conflict","Layout berubah lagi di perangkat lain; state terbaru dimuat")}catch(G){k(G)}return!1}}}),[S,C,k]),D=_.useCallback(p=>{const c=Rr(g.current,p);j(c);const L=Te(c);Qe(e,{workspace:L,revision:b.current,active:c.active})},[j,e]);return{workspace:a,status:s,message:v,writable:I,mutate:w,setActive:D,refresh:M}}function Yr({userId:e="test-user",projects:n,backlog:a=[],focusSession:i,onOpenReview:s,onOpenSessionReview:d,titleOf:v,onIntegrate:h,onIntegrateSession:I,specOf:T}){var u;const[g,b]=l.useState([]),[N,z]=l.useState([]),E=Dr(e),{workspace:j,status:f,message:C,writable:S,mutate:k,setActive:M,refresh:w}=E,[D,p]=De("terminal","project",((u=n[0])==null?void 0:u.id)??"",fn),c=Lt(),[L,B]=De("terminal","fontSize",c?Dn:lt,pn),[x,H]=De("terminal","keys",c,Ve),[q,A]=De("terminal","predict",!0,Ve),[G,te]=De("terminal","diag",!1,Ve),ne=r=>B(o=>tt(o+r)),[U,le]=l.useState(!1),[V,J]=l.useState(null),[Y,X]=l.useState(!1),[Q,re]=l.useState(null),[ce,he]=l.useState(!1),[ue,O]=l.useState(!1),K=cn()==="mobile",[R,ae]=l.useState(0),[ie,se]=l.useState(null),we=l.useRef(null),[ge,Fe]=l.useState(!1);l.useEffect(()=>{F.listTerminals().then(r=>{b(r),Fe(!0)}).catch(()=>{})},[]),l.useEffect(()=>un(r=>{r.t==="sessions"?b(r.sessions):r.t==="cleanups"&&z(r.cleanups)}),[]),l.useEffect(()=>{if(!ge||!S)return;const r=new Set(g.map(m=>m.id)),o=Tt(j,r);At(Te(o),Te(j))||k(m=>Tt(m,r))},[k,g,ge,S,j]),l.useEffect(()=>{if(!i){we.current=null;return}!ge||we.current===i||g.some(r=>r.id===i&&!r.exited)&&(we.current=i,se(i))},[i,g,ge]),l.useEffect(()=>{if(!ie)return;const r=j.groups.find(o=>o.layout.cells.includes(ie));if(r){r.id!==j.active&&M(r.id);return}S&&k(o=>{if(Et(o).has(ie))return o;const m=Ee(o,ie);return m!==o||!K?m:rt(o,R,ie)})},[R,K,k,ie,M,S,j]),l.useEffect(()=>{V&&!g.some(r=>r.id===V)&&J(null)},[V,g]);const Re=N.filter(r=>r.error),Se=r=>g.find(o=>o.id===r)??null,ye=r=>{var o;return((o=n.find(m=>m.id===r))==null?void 0:o.name)??r};function ze(r){b(o=>o.some(m=>m.id===r)?o:[...o,{id:r,projectId:D,cwd:"",exited:!1}]),k(o=>Ee(o,r)),se(r)}async function Ae(){if(!D)return;const{id:r}=await F.createShell(D);b(o=>[...o,{id:r,projectId:D,cwd:"",exited:!1}]),k(o=>Ee(o,r)),se(r)}async function Ue(r){const o=xn(r.source);try{const{id:m}=await F.startSession({spec:r.id,flow:o});b(y=>y.some(Z=>Z.id===m)?y:[...y,{id:m,projectId:r.projectId,specId:r.id,flow:o,cwd:"",exited:!1}]),k(y=>Ee(y,m)),se(m),X(!1),re(null)}catch(m){const y=m instanceof st&&(m.status===400||m.status===422);re(`${r.id} · gagal mulai${y?" · project belum punya repoDir":""}`)}}async function $(r){try{const o=r.specId?await F.startSession({spec:r.specId,flow:r.flow??"feature"}):r.kind==="shell"?await F.createShell(r.projectId):r.kind==="terminal"?await F.createTerminal(r.projectId,{agent:r.agent==="codex"?"codex":"claude",...r.model?{model:r.model}:{},...r.effort?{effort:r.effort}:{}}):await F.createTerminalFlow(r.projectId,r.kind);b(m=>m.some(y=>y.id===o.id)?m:[...m,{id:o.id,projectId:r.projectId,specId:r.specId??void 0,cwd:"",exited:!1}]),k(m=>Ee(m,o.id)),se(o.id),O(!1)}catch{}}const Le=new Set(g.filter(r=>r.specId&&!r.exited).map(r=>r.specId)),xe=a.filter(r=>r.stage!=="done"&&!Le.has(r.id));function pe(r){b(o=>o.filter(m=>m.id!==r)),F.deleteTerminal(r).catch(()=>{})}const ke=l.useCallback((r,o)=>{b(m=>m.map(y=>y.id===r?{...y,exited:!0,exitCode:o}:y))},[]),Ce=(r,o)=>{ae(r),k(m=>rt(m,r,o))},je=r=>{se(r),k(o=>Ee(o,r))},Oe=r=>{k(o=>zr(o,r))},We=Et(j),Ie=g.filter(r=>!We.has(r.id)),P=Pe(j).layout;l.useEffect(()=>{if(!ie)return;const r=P.cells.indexOf(ie);r<0||(ae(r),se(null))},[P.cells,ie]),l.useEffect(()=>{R>=P.cells.length&&ae(Math.max(0,P.cells.length-1))},[R,P.cells.length]);const Ne=P.rows===1&&P.cols===1&&!P.cells[0]&&g.length===0,_e=t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:10,marginBottom:10},children:[t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Ukuran teks terminal"}),t.jsx(Xe,{size:"sm",icon:"minus",label:"Perkecil teks terminal",disabled:L<=Dt,onClick:()=>ne(-1)}),t.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,minWidth:44,textAlign:"center"},children:[L,"px"]}),t.jsx(Xe,{size:"sm",icon:"plus",label:"Perbesar teks terminal",disabled:L>=Bt,onClick:()=>ne(1)})]}),t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Papan tombol layar (Esc · panah · Enter)"}),t.jsx(ee,{size:"sm",variant:"secondary","aria-pressed":x,onClick:()=>H(r=>!r),children:x?"Sembunyikan":"Tampilkan"})]}),t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Ketik responsif (huruf tampil sebelum echo server)"}),t.jsx(ee,{size:"sm",variant:"secondary","aria-pressed":q,"aria-label":`${q?"Matikan":"Nyalakan"} ketik responsif`,onClick:()=>A(r=>!r),children:q?"Matikan":"Nyalakan"})]}),t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Rekam jalur ketik (diagnostik — merekam setiap tombol)"}),t.jsx(ee,{size:"sm",variant:"secondary","aria-pressed":G,"aria-label":`${G?"Matikan":"Nyalakan"} rekam jalur ketik`,onClick:()=>te(r=>!r),children:G?"Matikan":"Nyalakan"})]}),K&&t.jsx(me,{size:"sm","aria-label":"Project sesi baru",value:D,onChange:r=>p(r.target.value),options:n.map(r=>({value:r.id,label:r.name}))})]}),Ke=[{key:"backlog",label:"Ambil backlog",icon:"inbox",onSelect:()=>{re(null),X(!0)}},{key:"history",label:"Riwayat sesi",icon:"history",onSelect:()=>O(!0)},{key:"shell",label:"Terminal biasa",icon:"terminal",onSelect:()=>void Ae()},{key:"col+",label:"+ Kolom",icon:"columns-2",disabled:!S,onSelect:()=>void k(r=>be(r,wt))},{key:"row+",label:"+ Baris",icon:"rows-2",disabled:!S,onSelect:()=>void k(r=>be(r,jt))},{key:"col-",label:"Hapus kolom aktif",icon:"columns-2",disabled:!S||P.cols===1,onSelect:()=>void k(r=>be(r,o=>Ct(o,R%o.cols)))},{key:"row-",label:"Hapus baris aktif",icon:"rows-2",disabled:!S||P.rows===1,onSelect:()=>void k(r=>be(r,o=>St(o,Math.floor(R/o.cols))))}],He={display:"flex",flexDirection:"column",gap:U?8:12,...U?{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 t.jsxs("div",{"data-testid":"terminal-root",style:He,children:[t.jsxs("div",{style:{display:"flex",gap:8,flexDirection:U?"row":"column",alignItems:U?"center":"stretch"},children:[t.jsx($r,{compact:U,ws:j,writable:S,onSelect:M,onAdd:()=>void k(r=>Ir(r,`Grup ${r.groups.length+1}`)),onRename:(r,o)=>void k(m=>Er(m,r,o)),onRemove:r=>void k(o=>Tr(o,r))}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap",...U?{flex:1,minWidth:0}:{}},children:[!K&&t.jsxs(t.Fragment,{children:[t.jsx(ee,{size:"sm",variant:"ghost",disabled:!S,onClick:()=>void k(r=>be(r,wt)),children:"+ Kolom"}),t.jsx(ee,{size:"sm",variant:"ghost",disabled:!S,onClick:()=>void k(r=>be(r,jt)),children:"+ Baris"})]}),t.jsx("div",{style:{flex:1,minWidth:0}}),f!=="ready"&&t.jsx("span",{"data-testid":"terminal-workspace-status",title:C??void 0,style:{fontSize:12,color:f==="conflict"?"var(--status-warn)":"var(--text-muted)"},children:f==="loading"?"Memuat layout server…":f==="recovering"?t.jsxs(t.Fragment,{children:[t.jsx("span",{children:"Layout server belum tersambung"})," ",t.jsx("button",{type:"button",onClick:()=>void w(),children:"Retry"})]}):C??"Layout berubah di perangkat lain"}),N.length>0&&t.jsx("span",{"data-testid":"worktree-cleanups",title:N.map(r=>`${r.sessionId}${r.error?` — ${r.error}`:""}`).join(`
9
- `),style:{fontSize:12,color:Re.length?"var(--status-err)":"var(--text-muted)"},children:Re.length?`${Re.length} worktree gagal dibersihkan`:`membersihkan ${N.length} worktree…`}),!K&&t.jsxs(t.Fragment,{children:[t.jsx(me,{size:"sm",value:D,onChange:r=>p(r.target.value),options:n.map(r=>({value:r.id,label:r.name}))}),t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"inbox",onClick:()=>{re(null),X(!0)},children:"Ambil backlog"}),t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"history",title:"Riwayat sesi yang sudah berlalu — buka kembali atau baca transkripnya",onClick:()=>O(!0),children:"Riwayat"}),t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"terminal",title:"Buka shell tmux tanpa Claude di project terpilih — jalankan command di project",onClick:()=>void Ae(),children:"Terminal biasa"})]}),t.jsx(ee,{size:"sm",leftIcon:"plus",onClick:()=>he(!0),children:"Sesi baru"}),t.jsx(Nt,{label:K?"Aksi terminal lain":"Tampilan terminal",items:K?Ke:[],children:_e}),t.jsx(Xe,{size:"sm",icon:U?"minimize-2":"maximize-2",label:U?"Keluar layar penuh":"Layar penuh","aria-pressed":U,onClick:()=>le(r=>!r)})]})]}),Ie.length>0&&t.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap",alignItems:"center"},children:[t.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"Belum di grid:"}),Ie.map(r=>t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6,padding:"4px 8px",borderRadius:"var(--radius-sm)",background:"var(--bone-200)",border:"1px solid var(--border-hair)",fontFamily:"var(--font-mono)",fontSize:11},children:[t.jsxs("button",{className:"hn-terminal-unplaced-action",disabled:!S,onClick:()=>je(r.id),title:"Taruh di sel kosong pertama grup ini",style:{all:"unset",cursor:"pointer"},children:[r.specId??ye(r.projectId)," · ",r.id.slice(0,6)]}),t.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${r.id}`,onClick:()=>void pe(r.id),children:"×"})]},r.id))]}),K&&!Ne&&t.jsx("div",{className:"hn-stack-mobile",style:{display:"flex",alignItems:"center",gap:8},children:t.jsx(dn,{"aria-label":"Panel terminal",variant:"pill",value:String(R),onChange:r=>ae(Number(r)),tabs:P.cells.map((r,o)=>({value:String(o),label:`Panel ${o+1}${r?` · ${r.slice(0,6)}`:" · kosong"}`}))})}),Ne?t.jsx(it,{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."}):t.jsxs("div",{style:{flex:1,minHeight:0,display:"grid",gap:8,gridTemplateColumns:K?"minmax(0, 1fr)":`18px repeat(${P.cols}, minmax(0, 1fr))`,gridTemplateRows:K?"minmax(0, 1fr)":`16px repeat(${P.rows}, minmax(0, 1fr))`},children:[!K&&t.jsx("div",{}),!K&&Array.from({length:P.cols},(r,o)=>t.jsx(Rt,{label:`Tutup kolom ${o+1}`,disabled:!S||P.cols===1,onClick:()=>void k(m=>be(m,y=>Ct(y,o)))},`col-${o}`)),Array.from({length:P.rows},(r,o)=>t.jsxs(l.Fragment,{children:[!K&&t.jsx(Rt,{label:`Tutup baris ${o+1}`,disabled:!S||P.rows===1,onClick:()=>void k(m=>be(m,y=>St(y,o)))}),Array.from({length:P.cols},(m,y)=>{const Z=o*P.cols+y,de=P.cells[Z]??null,oe=de?Se(de):null;return t.jsx("div",{"data-terminal-cell-index":Z,"aria-hidden":K&&R!==Z?"true":"false",style:{minHeight:0,minWidth:0,display:K&&R!==Z?"none":"flex",flexDirection:"column",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden"},children:oe?t.jsx(Or,{session:oe,nameOf:ye,onClose:()=>void pe(oe.id),canArrange:S,onDetach:()=>Oe(oe.id),onExit:fe=>ke(oe.id,fe),onReview:s,onSessionReview:d,titleOf:v,onIntegrate:h,onIntegrateSession:I,specOf:T,fontSize:L,showKeys:x,predict:q,diag:G,fullscreen:V===oe.id,onFullscreen:()=>J(oe.id)}):t.jsx(_r,{disabled:!S,unplaced:Ie,nameOf:ye,onPick:fe=>Ce(Z,fe)})},de??`empty-${Z}`)})]},`row-${o}`))]}),Y&&t.jsx(Br,{seed:xe,activeIds:Le,error:Q,onPick:r=>void Ue(r),onClose:()=>X(!1)}),ce&&t.jsx(wr,{open:!0,projectId:D,projectName:ye(D),onClose:()=>he(!1),onCreated:ze}),ue&&t.jsx(kr,{projects:n,onClose:()=>O(!1),onRestart:r=>void $(r)}),V&&Se(V)&&t.jsx(Wr,{session:Se(V),label:Ut(Se(V),ye,v),fontSize:L,showKeys:x,predict:q,diag:G,onClose:()=>J(null)})]})}function Ut(e,n,a){const i=n(e.projectId),s=e.specId?a==null?void 0:a(e.specId):void 0;return e.specId?`${i} · ${e.specId}${s?` · ${s}`:""}`:e.id.startsWith("xaudit-")?`${i} · audit lintas`:i}function Br({seed:e,activeIds:n,error:a,onPick:i,onClose:s}){const[d,v]=l.useState(""),[h,I]=l.useState("all"),[T,g]=l.useState("all"),[b,N]=l.useState(e),[z,E]=l.useState("");l.useEffect(()=>{const f=setTimeout(()=>E(d.trim()),250);return()=>clearTimeout(f)},[d]),l.useEffect(()=>{var S,k;let f=!0;const C=(k=(S=F).listSpecs)==null?void 0:k.call(S,{startable:!0,q:z||void 0,stage:h==="all"?void 0:h,priority:T==="all"?void 0:T});return C==null||C.then(M=>{f&&N(M.items)}).catch(()=>{}),()=>{f=!1}},[z,h,T]);const j=b.filter(f=>!n.has(f.id));return t.jsxs($e,{open:!0,title:"Ambil backlog",icon:"inbox",onClose:s,width:760,children:[a&&t.jsx("div",{style:{marginBottom:10,padding:"8px 10px",borderRadius:"var(--radius-sm)",background:"var(--clay-100)",color:"var(--clay-600)",fontSize:12},children:a}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",marginBottom:10},children:[t.jsx(at,{size:"sm",leftIcon:"search",placeholder:"mis. invoice atau SPEC-412","aria-label":"Cari backlog",value:d,onChange:f=>v(f.target.value),style:{flex:"1 1 220px"}}),t.jsx(me,{size:"sm","aria-label":"Filter stage",value:h,onChange:f=>I(f.target.value),options:[{value:"all",label:"Semua stage"}].concat(gn.filter(f=>f.key!=="done").map(f=>({value:f.key,label:f.label})))}),t.jsx(me,{size:"sm","aria-label":"Filter prioritas",value:T,onChange:f=>g(f.target.value),options:[{value:"all",label:"Semua prioritas"},{value:"tinggi",label:"Tinggi"},{value:"sedang",label:"Sedang"},{value:"rendah",label:"Rendah"}]})]}),j.length===0?t.jsx(it,{kind:"empty",icon:"inbox",title:"Tak ada backlog untuk diambil",hint:"Semua item sudah selesai/aktif atau tak cocok filter — buat brief baru di halaman Backlog."}):t.jsx("div",{style:{display:"flex",flexDirection:"column",maxHeight:"62vh",overflowY:"auto"},children:j.map(f=>t.jsx("button",{onClick:()=>i(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:t.jsxs("span",{className:"hn-dense-row hn-picker-row",style:{display:"flex",alignItems:"center",gap:10,width:"100%"},children:[t.jsx(ve,{name:f.source==="qa"?"bug":f.source==="audit"?"search":"lightbulb",size:14,color:f.source==="qa"?"var(--clay-500)":f.source==="audit"?"var(--wind-600)":"var(--brass-500)"}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-subtle)",flex:"0 0 78px"},children:f.id}),t.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}),t.jsx(et,{tone:f.priority==="tinggi"?"err":"neutral",size:"sm",children:f.priority}),t.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 $r({ws:e,compact:n=!1,writable:a,onSelect:i,onAdd:s,onRename:d,onRemove:v}){const[h,I]=l.useState(null),T=Pe(e),g=e.groups.length===1;return t.jsxs("div",{role:"tablist","aria-label":"Grup terminal",style:{display:"flex",alignItems:"center",gap:4,flexWrap:"wrap",...n?{}:{borderBottom:"1px solid var(--border-hair)",paddingBottom:4}},children:[e.groups.map((b,N)=>{const z=b.id===T.id;return h===b.id?t.jsx(Mr,{initial:b.name,onCommit:E=>{E.trim()&&d(b.id,E.trim()),I(null)},onCancel:()=>I(null)},b.id):t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4,padding:"3px 6px",borderRadius:"var(--radius-sm)",fontSize:12,background:z?"var(--bone-200)":"transparent",border:`1px solid ${z?"var(--border-hair)":"transparent"}`},children:[t.jsx("button",{className:"hn-terminal-group-control",role:"tab","aria-selected":z,tabIndex:z?0:-1,onClick:()=>i(b.id),onKeyDown:E=>{var f,C;let j=null;E.key==="ArrowRight"?j=(N+1)%e.groups.length:E.key==="ArrowLeft"?j=(N-1+e.groups.length)%e.groups.length:E.key==="Home"?j=0:E.key==="End"&&(j=e.groups.length-1),j!==null&&(E.preventDefault(),i(e.groups[j].id),(C=(f=E.currentTarget.closest('[role="tablist"]'))==null?void 0:f.querySelectorAll('[role="tab"]')[j])==null||C.focus())},style:{border:0,padding:0,background:"transparent",font:"inherit",cursor:"pointer",color:z?"var(--text-strong)":"var(--text-muted)"},children:b.name}),z&&a&&t.jsxs(t.Fragment,{children:[t.jsx("button",{className:"hn-terminal-group-control","aria-label":`Ganti nama grup ${b.name}`,title:"Ganti nama",onClick:()=>I(b.id),style:{border:0,padding:0,background:"transparent",cursor:"pointer",color:"var(--text-subtle)",fontSize:10},children:"✎"}),t.jsx("button",{className:"hn-terminal-group-control","aria-label":`Hapus grup ${b.name}`,title:g?"Grup terakhir tak bisa dihapus":"Hapus grup (sesi tetap hidup)",disabled:g,onClick:()=>v(b.id),style:{border:0,padding:0,background:"transparent",cursor:g?"not-allowed":"pointer",color:"var(--text-subtle)",opacity:g?.35:1},children:"×"})]})]},b.id)}),t.jsx("button",{className:"hn-terminal-group-control","aria-label":"Grup baru",title:"Grup baru",disabled:!a,onClick:s,style:{border:0,background:"transparent",cursor:"pointer",padding:"3px 8px",color:"var(--text-subtle)",fontSize:12},children:"+"})]})}function Rt({label:e,disabled:n,onClick:a}){return t.jsx("button",{type:"button","aria-label":e,title:n?"Grid tak boleh menyusut ke nol":e,disabled:n,onClick:a,style:{all:"unset",display:"grid",placeItems:"center",fontSize:11,lineHeight:1,color:"var(--text-subtle)",opacity:n?.3:1,cursor:n?"not-allowed":"pointer"},children:"×"})}function Mr({initial:e,onCommit:n,onCancel:a}){const[i,s]=l.useState(e);return t.jsx("input",{autoFocus:!0,"aria-label":"Nama grup",value:i,placeholder:"mis. Rilis",onChange:d=>s(d.target.value),onBlur:()=>n(i),onKeyDown:d=>{d.key==="Enter"?n(i):d.key==="Escape"&&a()},style:{width:100,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 Pr={done:"var(--brass)",active:"var(--text-strong)",skipped:"var(--text-subtle)",pending:"var(--text-subtle)"};function Fr({phases:e}){return e!=null&&e.length?t.jsx("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"3px 8px",flex:"0 0 auto",borderBottom:"1px solid var(--border-hair)",fontSize:10,fontFamily:"var(--font-mono)"},children:e.map(n=>t.jsx("span",{"data-state":n.state,title:n.state,style:{color:Pr[n.state],fontWeight:n.state==="active"?600:400,textDecoration:n.state==="skipped"?"line-through":"none",opacity:n.state==="pending"?.5:1},children:n.name},n.name))}):null}function Or({session:e,nameOf:n,onClose:a,canArrange:i,onDetach:s,onExit:d,onReview:v,onSessionReview:h,titleOf:I,onIntegrate:T,onIntegrateSession:g,specOf:b,fontSize:N,showKeys:z,predict:E,diag:j,fullscreen:f,onFullscreen:C}){const[S,k]=l.useState(null),M=l.useRef(null),[w,D]=l.useState(Number.POSITIVE_INFINITY),p=Lt();l.useEffect(()=>{const O=M.current;if(!O||typeof ResizeObserver!="function")return;const W=new ResizeObserver(K=>{var ae;const R=((ae=K[0])==null?void 0:ae.contentRect.width)??O.getBoundingClientRect().width;R>0&&D(R)});return W.observe(O),()=>W.disconnect()},[]);const[c,L]=l.useState(!1),B=l.useCallback((O,W)=>{k(O),L(W)},[]),[x,H]=l.useState(!1),[q,A]=l.useState(!1),[G,te]=l.useState(!1),ne=e.specId?b==null?void 0:b(e.specId):void 0,U=!e.specId&&!!e.branch,le=Ut(e,n,I),V=!e.exited&&!!e.decision,J=!e.exited&&!!e.deciding,Y=V||J,X=e.exited&&!!e.exitCode,Q=!e.exited&&c,re=X?null:e.exited||Q?"PST-005":Y?"PST-004":"PST-003",ce=[...e.specId?[{key:"docs",label:"Lihat dokumen",icon:"file-text",title:"Lihat dokumen (audit/spec/plan)",onSelect:()=>H(!0),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>H(!0),"aria-label":`Lihat dokumen sesi ${e.id}`,title:"Lihat dokumen (audit/spec/plan)",children:t.jsx(ve,{name:"file-text",size:12})},"docs")}]:[],...e.specId&&v?[{key:"review",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree)",onSelect:()=>v(e.specId),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>v(e.specId),"aria-label":`Review sesi ${e.id}`,title:"Review perubahan (diff worktree)",children:t.jsx(ve,{name:"git-compare",size:12})},"review")}]:[],...U&&h?[{key:"review-session",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree sesi)",onSelect:()=>h(e.id,le),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>h(e.id,le),"aria-label":`Review sesi ${e.id}`,title:"Review perubahan (diff worktree sesi)",children:t.jsx(ve,{name:"git-compare",size:12})},"review-session")}]:[],...ne&&T?[{key:"integrate",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch spec",onSelect:()=>A(!0),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>A(!0),"aria-label":`Integrasikan sesi ${e.id}`,title:"Rebase / Merge branch spec",children:t.jsx(ve,{name:"git-merge",size:12})},"integrate")}]:[],...U&&g?[{key:"integrate-session",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch sesi",onSelect:()=>te(!0),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>te(!0),"aria-label":`Integrasikan sesi ${e.id}`,title:"Rebase / Merge branch sesi",children:t.jsx(ve,{name:"git-merge",size:12})},"integrate-session")}]:[],{key:"detach",label:"Lepas dari grid",icon:"unlink",disabled:!i,title:"Lepas dari grid (sesi tetap hidup)",onSelect:s,render:t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:s,disabled:!i,title:"Lepas dari grid (sesi tetap hidup)",children:"lepas"},"detach")}],he=Rn(w,ce.length,p?44:28),ue=ce.slice(he);return t.jsxs(t.Fragment,{children:[t.jsxs("div",{ref:M,className:"hn-terminal-cell-header",style:{display:"flex",alignItems:"center",gap:8,padding:"4px 8px",flex:"0 0 auto",background:X?"var(--status-err-tint)":e.exited||Q?"var(--status-ok-tint)":Y?"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&&t.jsx(mn,{id:re,decorative:!0,style:{width:34,flex:"0 0 auto",borderRadius:"var(--radius-sm)"}}),t.jsxs("span",{style:{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:[le," · ",e.id.slice(0,6)]}),e.exited&&(X?t.jsx(Be,{status:"failed",size:"sm",children:`Gagal · exit ${e.exitCode}`}):t.jsx(Be,{status:"done",size:"sm",children:"Selesai"})),Q&&t.jsx(Be,{status:"done",size:"sm",children:"Selesai"}),J&&!Q&&t.jsx(Be,{status:"running",size:"sm",children:"Lead memutuskan"}),V&&!J&&!Q&&t.jsx(Be,{status:"awaiting",size:"sm"}),t.jsxs("span",{className:"hn-terminal-actions",children:[ce.slice(0,he).map(O=>O.render),ue.length>0&&t.jsx(Nt,{label:`Aksi lain sesi ${e.id}`,items:ue.map(({render:O,...W})=>W)}),t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:C,title:"Layar penuh — fokus 1 terminal","aria-label":`Layar penuh sesi ${e.id}`,children:t.jsx(ve,{name:"fullscreen",size:12})}),t.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${e.id}`,onClick:a,children:"×"})]})]}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",flex:1,minHeight:0,opacity:e.exited?.6:1},children:[t.jsx(Fr,{phases:S}),t.jsx("div",{style:{flex:1,minHeight:0},children:f?t.jsx("div",{style:{height:"100%",display:"grid",placeItems:"center",padding:12,color:"var(--text-subtle)",fontSize:12,textAlign:"center"},children:"Terbuka di layar penuh"}):t.jsx(Ot,{sessionId:e.id,onExit:d,onPhases:B,fontSize:N,showKeys:z,predict:E,diag:j},e.id)})]}),x&&e.specId&&t.jsx(hn,{specId:e.specId,onClose:()=>H(!1)}),q&&ne&&T&&t.jsx(gt,{projectId:ne.projectId,ownBranch:`hanoman/${ne.id.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,eyebrow:ne.id,onClose:()=>A(!1),onIntegrate:(O,W)=>{A(!1),T(ne,O,W)}}),G&&U&&g&&t.jsx(gt,{projectId:e.projectId,ownBranch:e.branch,eyebrow:e.id.slice(0,16),onClose:()=>te(!1),onIntegrate:(O,W)=>{te(!1),g(e,O,W)}})]})}function Wr({session:e,label:n,fontSize:a,showKeys:i,predict:s,diag:d,onClose:v}){return t.jsx($e,{open:!0,icon:"terminal",title:n,onClose:v,closeOnEscape:!1,width:1600,children:t.jsx("div",{style:{height:"min(72vh, calc(100dvh - 180px))",minHeight:0,display:"flex",flexDirection:"column",opacity:e.exited?.6:1},children:t.jsx(Ot,{sessionId:e.id,onExit:()=>{},fontSize:a,showKeys:i,predict:s,diag:d},e.id)})})}function _r({unplaced:e,nameOf:n,onPick:a,disabled:i}){return t.jsx("div",{style:{flex:1,display:"grid",placeItems:"center",padding:12},children:t.jsx(me,{size:"sm",value:"","aria-label":"Pilih sesi untuk sel",disabled:i||!e.length,onChange:s=>s.target.value&&a(s.target.value),options:[{value:"",label:e.length?"Pilih sesi…":"tidak ada sesi bebas"}].concat(e.map(s=>({value:s.id,label:`${s.specId??n(s.projectId)} · ${s.id.slice(0,6)}`})))})})}export{Fr as PhaseStrip,Yr as TerminalScreen};