hanoman 0.9.28 → 0.9.29
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.
- package/README.md +5 -2
- package/dist/build-info.json +3 -3
- package/dist/cli.js +337 -90
- package/dist/server.js +2677 -1389
- package/docs/agent-integration.md +100 -6
- package/package.json +1 -1
- package/prisma/migrations/20261014130000_cron_report/migration.sql +19 -0
- package/prisma/schema.prisma +25 -0
- package/scripts/vps/provision.sh +26 -3
- package/web/assets/{DalangHanomanScreen-C3UMPHFg.js → DalangHanomanScreen-BMrikKnt.js} +1 -1
- package/web/assets/{DocPreviewModal-Bp5stb4M.js → DocPreviewModal-5j31WUwI.js} +1 -1
- package/web/assets/{DocsWorkspace-C9yFxK4D.js → DocsWorkspace-GkTrniF3.js} +1 -1
- package/web/assets/{IdeScreen-CRFRAP6E.js → IdeScreen-CAQfv1_e.js} +1 -1
- package/web/assets/LeadScreen-Da5-1FLe.js +1 -0
- package/web/assets/{ReviewScreen-CMHOlmgX.js → ReviewScreen-B8KHzQpd.js} +1 -1
- package/web/assets/SchedulerScreen-CBd4O5kw.js +1 -0
- package/web/assets/SettingsScreen-BxQ3CH2D.js +62 -0
- package/web/assets/{TeamScreen-D4tA34Mj.js → TeamScreen-P6vz88Pp.js} +1 -1
- package/web/assets/TerminalScreen-B_cagBZd.js +2 -0
- package/web/assets/{TriageScreen-B8ZCexaX.js → TriageScreen-IYkxyhdm.js} +1 -1
- package/web/assets/{VpsScreen-BCrLfZh7.js → VpsScreen-DFGT5S8Y.js} +2 -2
- package/web/assets/fields-CmVwp6QK.js +1 -0
- package/web/assets/{index-BqAP-VDq.css → index-0T3s-I82.css} +1 -1
- package/web/assets/index-C-iSWHn3.js +1012 -0
- package/web/assets/{live-DuBdI0MZ.js → live-lSo-u7M6.js} +1 -1
- package/web/assets/{sched-lead-shared-QqbtjoVv.js → sched-lead-shared-BTz6aILx.js} +1 -1
- package/web/assets/{scheduler-CQt-VP9-.css → scheduler-D64RlGvZ.css} +1 -1
- package/web/assets/settings-rebase-CPawFVpp.js +1 -0
- package/web/index.html +2 -2
- package/web/assets/LeadScreen-DfVUawoK.js +0 -1
- package/web/assets/SchedulerScreen-CK5QvX5c.js +0 -1
- package/web/assets/SettingsScreen-D7P5JgjU.js +0 -62
- package/web/assets/TerminalScreen-CKySL63X.js +0 -2
- package/web/assets/index-BRR3JL_o.js +0 -1012
- package/web/assets/settings-rebase-Cbh-JGJ-.js +0 -1
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{h as $,i as ne,j as a,M as se,f as fa,g as Q,a3 as pn,a4 as ga,m as Re,n as bt,I as Ee,a2 as hn,Z as fn,B,a5 as gn,C as Ye,a6 as Yt,a7 as Jt,e as Te,a8 as bn,a9 as kn,aa as xn,ab as vn,ac as jn,ad as yn,ae as Ae,af as ba,ag as ze,ah as wn,r as Sn,a1 as Nn,Y as me,O as ye,ai as In,aj as Cn,ak as kt,al as Tn,q as de,am as ka,b as Rn,an as En,d as zn,ao as An,p as Dn,ap as Mn,aq as Xt,ar as $n,o as pt,as as Fn,at as Pn,c as Ln,au as On,av as Zt,aw as Bn,ax as Kn,V as _n,ay as Gn,az as Wn,aA as Ue,aB as jt,aC as qn,aD as Un,D as Hn,aE as Vn,aF as Qt,aG as Yn}from"./index-BRR3JL_o.js";import{R as d,r as P}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import"./xterm-3VOAfa_q.js";function yt(e){return e.endedAt?e.endedReason==="reconciled"?"interrupted":e.exitCode===null||e.exitCode===0?"completed":"failed":"running"}const He=new Set;let Ce;function Jn(e){return He.add(e),Ce||(Ce=setInterval(()=>{for(const n of[...He])n()},1e3)),()=>{He.delete(e),He.size===0&&Ce&&(clearInterval(Ce),Ce=void 0)}}const ea=20;function Xn(e,n){if(!n)return"—";const s=new Date(n).getTime()-new Date(e).getTime();if(!Number.isFinite(s)||s<0)return"—";const r=Math.round(s/1e3);if(r<60)return`${r} dtk`;const l=Math.round(r/60);return l<60?`${l} mnt`:`${Math.floor(l/60)} jam ${l%60} mnt`}function Zn(e){switch(yt(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 xa=e=>yt(e)==="interrupted"?"—":Xn(e.startedAt,e.endedAt),va=e=>ga[e]??e;function Qn({projects:e,onClose:n,onRestart:s}){const[r,l]=d.useState([]),[c,x]=d.useState(0),[g,S]=d.useState(1),[f,k]=d.useState(!1),[p,b]=d.useState(""),[y,I]=d.useState(""),[E,z]=d.useState(""),[R,j]=d.useState(""),[h,M]=d.useState(null),[K,_]=d.useState(null),[v,N]=d.useState(0);d.useEffect(()=>{const o=setTimeout(()=>j(E.trim()),250);return()=>clearTimeout(o)},[E]),d.useEffect(()=>{S(1)},[p,y,R]),d.useEffect(()=>{let o=!0;return k(!0),$.listSessionHistory({projectId:p||void 0,kind:y||void 0,q:R||void 0,page:g,limit:ea}).then(T=>{o&&(_(null),x(T.total),l(T.items))}).catch(T=>{o&&(l([]),x(0),_(ne("memuat riwayat sesi",T)))}).finally(()=>{o&&k(!1)}),()=>{o=!1}},[p,y,R,g,v]);const D=fn(c,g,ea),w=o=>{var T;return((T=e.find(H=>H.id===o))==null?void 0:T.name)??o};return a.jsxs(se,{open:!0,title:"Riwayat sesi",icon:"history",onClose:n,width:900,children:[a.jsxs("div",{className:"hn-terminal-hist-toolbar",children:[a.jsx(fa,{size:"sm",leftIcon:"search",placeholder:"mis. spec-412 atau reverse","aria-label":"Cari riwayat sesi",value:E,onChange:o=>z(o.target.value),className:"hn-terminal-hist-search"}),a.jsx(Q,{size:"sm","aria-label":"Filter project",value:p,onChange:o=>b(o.target.value),options:[{value:"",label:"Semua project"}].concat(e.map(o=>({value:o.id,label:o.name})))}),a.jsx(Q,{size:"sm","aria-label":"Filter jenis",value:y,onChange:o=>I(o.target.value),options:[{value:"",label:"Semua jenis"}].concat(pn.map(o=>({value:o,label:ga[o]})))})]}),K?a.jsx(Re,{kind:"error",icon:"history",title:"Riwayat belum bisa dimuat",hint:K,action:()=>N(o=>o+1),actionLabel:"Coba lagi"}):r.length===0&&!f?a.jsx(Re,{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",{className:"hn-terminal-hist-list",children:[r.map(o=>{const T=Zn(o);return a.jsx("button",{onClick:()=>M(o),className:"hn-terminal-hist-row",children:a.jsxs("span",{className:"hn-dense-row hn-picker-row hn-terminal-hist-main",children:[a.jsx("span",{className:"hn-terminal-hist-when",children:new Date(o.startedAt).toLocaleString("id-ID")}),a.jsx(bt,{size:"sm",tone:"neutral",children:va(o.kind)}),a.jsx("span",{className:"hn-picker-title hn-terminal-hist-title",children:o.title??o.specId??w(o.projectId)}),o.transcriptBytes!==null&&a.jsx(Ee,{name:"file-text",size:12,color:"var(--text-subtle)"}),a.jsx("span",{className:"hn-terminal-hist-duration",children:xa(o)}),a.jsx(bt,{size:"sm",tone:T.tone,children:T.label})]})},o.id)}),f&&a.jsx("div",{className:"hn-terminal-hist-loading",children:"memuat…"})]}),a.jsx(hn,{page:D.page,pageCount:D.pageCount,total:c,from:D.from,to:D.to,onPage:S,unit:"sesi"}),h&&a.jsx(es,{row:h,projectName:w(h.projectId),onBack:()=>M(null),onRestart:s})]})}function es({row:e,projectName:n,onBack:s,onRestart:r}){const[l,c]=d.useState(null),[x,g]=d.useState("idle"),[S,f]=d.useState(null);async function k(y){try{if(!navigator.clipboard)throw new Error("clipboard tidak tersedia di browser ini");await navigator.clipboard.writeText(y),f({tone:"ok",text:"Transkrip disalin."})}catch(I){f({tone:"err",text:ne("menyalin transkrip",I)})}}d.useEffect(()=>{if(e.transcriptBytes===null){g("none"),c(null);return}let y=!0;return g("loading"),$.sessionTranscript(e.id).then(I=>{y&&(c(I.text),g("idle"))}).catch(()=>{y&&(c(null),g("error"))}),()=>{y=!1}},[e.id,e.transcriptBytes]);const p=yt(e)==="interrupted",b=[["Project",n],["Sesi",e.sessionId],["Jenis",va(e.kind)],["Agen",[e.agent,e.model,e.effort].filter(Boolean).join(" · ")],["Mulai",new Date(e.startedAt).toLocaleString("id-ID")],[p?"Terakhir terlihat hidup":"Selesai",e.endedAt?new Date(e.endedAt).toLocaleString("id-ID"):"berjalan"],...p&&e.reconciledAt?[["Terdeteksi mati",new Date(e.reconciledAt).toLocaleString("id-ID")]]:[],["Durasi",xa(e)],["Direktori",e.cwd]];return e.specId&&b.splice(1,0,["Backlog",`${e.specId}${e.title?` · ${e.title}`:""}`]),e.branch&&b.push(["Branch",e.branch]),a.jsxs(se,{open:!0,title:e.title??e.specId??e.sessionId,icon:"history",onClose:s,width:1e3,children:[a.jsxs("div",{className:"hn-terminal-hist-actions",children:[a.jsx(B,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:s,children:"Kembali"}),a.jsx("div",{className:"hn-terminal-hist-spacer"}),l&&a.jsx(B,{size:"sm",variant:"secondary",leftIcon:"copy",onClick:()=>void k(l),children:"Salin transkrip"}),gn(e.kind)&&a.jsx(B,{size:"sm",leftIcon:"play",onClick:()=>r(e),children:"Mulai lagi"})]}),p&&a.jsxs(Ye,{tone:"warn",title:"Sesi terputus — hasilnya tak diketahui",className:"hn-terminal-notice",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",{className:"hn-terminal-hist-meta",children:b.map(([y,I])=>a.jsxs(d.Fragment,{children:[a.jsx("span",{className:"hn-terminal-hist-key",children:y}),a.jsx("span",{className:"hn-terminal-hist-val",children:I})]},y))}),x==="loading"&&a.jsx("div",{className:"hn-terminal-hist-note",children:"memuat transkrip…"}),x==="none"&&a.jsx("div",{className:"hn-terminal-hist-note",children:p?"Tanpa transkrip — panenya sudah lenyap sebelum hanoman sempat mengambilnya.":"Tanpa transkrip — sesi ini ditutup sebelum fitur riwayat ada, atau panenya tak menyisakan keluaran."}),S&&a.jsx("div",{role:"status",className:S.tone==="err"?"hn-terminal-hist-copy is-err":"hn-terminal-hist-copy",children:S.text}),x==="error"&&a.jsx("div",{className:"hn-terminal-hist-error",children:"Transkrip tak terbaca lagi di server."}),l!==null&&a.jsx("pre",{className:"hn-terminal-hist-pre",children:l})]})}function ts({open:e,projectId:n,projectName:s,projects:r,onProjectChange:l,onClose:c,onCreated:x}){var w;const[g,S]=d.useState("claude"),[f,k]=d.useState("sonnet"),[p,b]=d.useState("medium"),[y,I]=d.useState({claude:{model:"sonnet",effort:"medium"},codex:{...Yt}}),[E,z]=d.useState(!1),[R,j]=d.useState(null),[h,M]=d.useState(null),[K,_]=d.useState(null);d.useEffect(()=>{e&&(j(null),M(null),$.getSettings().then(o=>{const T={claude:{model:o.model,effort:o.effort},codex:{...Yt,...o.codex??{}}},H=o.agent==="codex"?"codex":"claude",L=Jt(T,H);I(T),S(H),k(L.model),b(L.effort)}).catch(o=>{j(`${ne("memuat pengaturan",o)} · memakai default bawaan`)}),$.getCodexVersion().then(o=>_(o.version)).catch(o=>{j(T=>(T?`${T} · `:"")+ne("membaca versi Codex CLI",o))}))},[e]);const v=o=>{S(o);const T=Jt(y,o);k(T.model),b(T.effort)},N=o=>{k(o),b(T=>g==="codex"?jn(o,T):yn(o,T))};async function D(){z(!0),M(null);try{const{id:o}=await $.createTerminal(n,{agent:g,model:f,effort:p});x(o),c()}catch(o){M(ne("membuka sesi",o))}finally{z(!1)}}return a.jsxs(se,{open:e,onClose:c,icon:"plus",eyebrow:s,title:"Sesi baru",footer:a.jsxs(a.Fragment,{children:[a.jsx(B,{variant:"ghost",onClick:c,children:"Batal"}),a.jsx(B,{leftIcon:"play",disabled:E,onClick:()=>void D(),children:"Buka sesi"})]}),children:[R&&a.jsx(Ye,{tone:"warn",title:"Pengaturan belum terbaca",className:"hn-terminal-notice",children:R}),h&&a.jsx(Ye,{tone:"err",title:"Sesi belum terbuka",className:"hn-terminal-notice",children:h}),a.jsxs("div",{className:"hn-terminal-intro",children:["Runtime untuk sesi ini. Default dari setelan global; ubah bila perlu. Sesi lahir dengan pilihan ini untuk seluruh hidupnya — ",a.jsx("code",{children:"/model"})," di terminal tetap bisa mengubahnya."]}),r&&l&&r.length>1&&a.jsx(Te,{label:"Project",hint:"Direktori repo tempat sesi dibuka.",children:a.jsx(Q,{"aria-label":"Project",value:n,className:"hn-terminal-field-full",options:r.map(o=>({value:o.id,label:o.name})),onChange:o=>l(o.target.value)})}),a.jsx(Te,{label:"Agen",hint:"Mesin yang menjalankan sesi ini. Perilaku sesi sama; hanya CLI-nya berbeda.",children:a.jsx(Q,{"aria-label":"Agen",value:g,className:"hn-terminal-field-full",options:[{value:"claude",label:"Claude Code"},{value:"codex",label:"Codex CLI"}],onChange:o=>v(o.target.value)})}),a.jsx(Te,{label:"Model",children:a.jsx(Q,{"aria-label":"Model",value:f,className:"hn-terminal-field-full",options:bn(g,f),onChange:o=>N(o.target.value)})}),a.jsx(Te,{label:"Effort",children:a.jsx(Q,{"aria-label":"Effort",value:p,className:"hn-terminal-field-full",options:kn(g,f).map(o=>({value:o,label:o})),onChange:o=>b(o.target.value)})}),g==="codex"&&xn(f,K)&&a.jsxs("div",{"data-testid":"codex-version-note",className:"hn-terminal-codex-note",children:["Codex CLI terpasang ",a.jsx("b",{children:K}),", sedangkan ",a.jsx("b",{children:f})," butuh ",a.jsx("b",{children:(w=vn(f))==null?void 0:w.minClient}),". Sesi tetap boleh dijalankan, tapi modelnya belum tentu dikenali CLI ini."]})]})}function as({projectId:e,projects:n,onProjectChange:s,onClose:r,onConfirm:l}){return a.jsx(se,{open:!0,onClose:r,icon:"terminal",title:"Terminal biasa",footer:a.jsxs(a.Fragment,{children:[a.jsx(B,{variant:"ghost",onClick:r,children:"Batal"}),a.jsx(B,{leftIcon:"play",disabled:!e,onClick:()=>l(e),children:"Buka terminal"})]}),children:a.jsx(Te,{label:"Project",hint:"Shell dibuka di direktori repo project ini.",children:a.jsx(Q,{"aria-label":"Project",value:e,className:"hn-terminal-field-full",options:n.map(c=>({value:c.id,label:c.name})),onChange:c=>s(c.target.value)})})})}const ja=()=>({rows:1,cols:1,cells:[null]}),ya=(e,n)=>[...e.slice(0,n),...e.slice(n+1)],ta=e=>({...e,rows:e.rows+1,cells:[...e.cells,...Array(e.cols).fill(null)],...e.rowSizes?{rowSizes:[...e.rowSizes,1]}:{}});function aa(e){const n=e.cols+1,s=[];for(let r=0;r<e.rows;r++)for(let l=0;l<n;l++)s.push(l<e.cols?e.cells[r*e.cols+l]??null:null);return{...e,cols:n,cells:s,...e.colSizes?{colSizes:[...e.colSizes,1]}:{}}}function na(e,n){if(e.rows===1||n<0||n>=e.rows)return e;const s=[...e.cells];return s.splice(n*e.cols,e.cols),{...e,rows:e.rows-1,cells:s,...e.rowSizes?{rowSizes:ya(e.rowSizes,n)}:{}}}function sa(e,n){if(e.cols===1||n<0||n>=e.cols)return e;const s=e.cols-1,r=[];for(let l=0;l<e.rows;l++)for(let c=0;c<e.cols;c++)c!==n&&r.push(e.cells[l*e.cols+c]??null);return{...e,cols:s,cells:r,...e.colSizes?{colSizes:ya(e.colSizes,n)}:{}}}const wa=.3,ns=(e,n,s)=>Math.min(s,Math.max(n,e));function wt(e,n,s){if(n<0||n+1>=e.length||s===0)return e;const l=e.reduce((S,f)=>S+f,0)/e.length*wa,c=e[n]+e[n+1],x=ns(e[n]+s,l,c-l);if(x===e[n])return e;const g=[...e];return g[n]=x,g[n+1]=c-x,g}function Sa(e,n,s){const r=e.colSizes??Array(e.cols).fill(1),l=wt(r,n,s);return l===r?e:{...e,colSizes:l}}function Na(e,n,s){const r=e.rowSizes??Array(e.rows).fill(1),l=wt(r,n,s);return l===r?e:{...e,rowSizes:l}}const ss=.05,is=.15,Ia=(e,n)=>e.reduce((s,r)=>s+r,0)*(n?is:ss);function rs(e,n,s,r=!1){const l=e.colSizes??Array(e.cols).fill(1);return Sa(e,n,s*Ia(l,r))}function ls(e,n,s,r=!1){const l=e.rowSizes??Array(e.rows).fill(1);return Na(e,n,s*Ia(l,r))}function ia(e,n){const r=e.reduce((x,g)=>x+g,0)/e.length*wa,l=e[n]+e[n+1],c=Math.round(r/l*100);return{now:Math.round(e[n]/l*100),min:c,max:100-c}}function xt(e,n,s){if(n<0||n>=e.cells.length)return e;const r=e.cells.map(l=>s!==null&&l===s?null:l);return r[n]=s,{...e,cells:r}}const os=(e,n)=>({...e,cells:e.cells.map(s=>s&&n.has(s)?s:null)}),Ca=e=>({id:crypto.randomUUID(),name:e,layout:ja()});function ra(){const e=Ca("Utama");return{groups:[e],active:e.id}}const De=e=>e.groups.find(n=>n.id===e.active)??e.groups[0];function cs(e,n){const s=Ca(n);return{groups:[...e.groups,s],active:s.id}}const us=(e,n,s)=>({...e,groups:e.groups.map(r=>r.id===n?{...r,name:s}:r)});function ds(e,n){if(e.groups.length===1)return e;const s=e.groups.filter(r=>r.id!==n);return s.length===e.groups.length?e:{groups:s,active:e.active===n?s[0].id:e.active}}const ms=(e,n)=>e.groups.some(s=>s.id===n)?{...e,active:n}:e;function U(e,n){const s=De(e);return{...e,groups:e.groups.map(r=>r.id===s.id?{...r,layout:n(r.layout)}:r)}}function vt(e,n,s){const r=De(e),l=s===null?e.groups:e.groups.map(c=>c.id===r.id?c:{...c,layout:xt(c.layout,c.layout.cells.indexOf(s),null)});return{...e,groups:l.map(c=>c.id===r.id?{...c,layout:xt(c.layout,n,s)}:c)}}function xe(e,n){const s=De(e).layout.cells.indexOf(null);return s===-1?e:vt(e,s,n)}const ps=(e,n)=>({...e,groups:e.groups.map(s=>({...s,layout:xt(s.layout,s.layout.cells.indexOf(n),null)}))}),la=e=>new Set(e.groups.flatMap(n=>n.layout.cells.filter(s=>s!==null))),oa=(e,n)=>({...e,groups:e.groups.map(s=>({...s,layout:os(s.layout,n)}))}),Ta="hanoman.terminal.workspace",Ra="hanoman.terminal.layout",ve=e=>Ae.parse({version:1,groups:e.groups});function Ve(e,n){const s=e.groups,r=n&&s.some(l=>l.id===n)?n:s[0].id;return{groups:s,active:r}}function hs(e){try{const n=JSON.parse(e);if(!n||typeof n!="object")return null;const s=n,r=Ae.parse({version:1,groups:s.groups});return{workspace:r,active:typeof s.active=="string"&&r.groups.some(l=>l.id===s.active)?s.active:r.groups[0].id}}catch{return null}}function fs(){try{const e=localStorage.getItem(Ta);if(e)return hs(e);const n=localStorage.getItem(Ra);if(!n)return null;const s=JSON.parse(n),r={id:crypto.randomUUID(),name:"Utama",layout:s};return{workspace:Ae.parse({version:1,groups:[r]}),active:r.id}}catch{return null}}function ht(){try{localStorage.removeItem(Ta),localStorage.removeItem(Ra)}catch{}}const Ea=e=>`hanoman.terminal.workspace.v2.${encodeURIComponent(e)}`;function gs(e){try{const n=localStorage.getItem(Ea(e));if(!n)return null;const s=JSON.parse(n),r=Ae.parse(s.workspace);if(!Number.isInteger(s.revision)||(s.revision??-1)<0)return null;const l=typeof s.active=="string"&&r.groups.some(c=>c.id===s.active)?s.active:r.groups[0].id;return{workspace:r,revision:s.revision,active:l}}catch{return null}}function ft(e,n){try{const s=Ae.parse(n.workspace);if(!Number.isInteger(n.revision)||n.revision<0)return;const r=s.groups.some(l=>l.id===n.active)?n.active:s.groups[0].id;localStorage.setItem(Ea(e),JSON.stringify({workspace:s,revision:n.revision,active:r}))}catch{}}function gt(e){if(!(e instanceof ze)||e.status!==409)return null;const n=e.detail;if((n==null?void 0:n.code)!=="revision-conflict")return null;const s=wn.safeParse(n.current);return s.success?s.data:null}function bs(e){const n=P.useRef(null);n.current||(n.current=ra());const[s,r]=P.useState(n.current),[l,c]=P.useState("loading"),[x,g]=P.useState(null),[S,f]=P.useState(!1),k=P.useRef(s),p=P.useRef(0),b=P.useRef(!1),y=P.useRef(Promise.resolve()),I=P.useRef(0),E=P.useCallback(v=>{k.current=v,r(v)},[]),z=P.useCallback(v=>{b.current=v,f(v)},[]),R=P.useCallback(v=>{const N=y.current.then(v,v);return y.current=N.then(()=>{},()=>{}),N},[]),j=P.useCallback((v,N="ready",D=null,w=k.current.active)=>{const o=v.workspace?Ve(v.workspace,w):ra();p.current=v.revision,E(o),c(N),g(D),z(!0),v.workspace&&ft(e,{workspace:v.workspace,revision:v.revision,active:o.active})},[E,z,e]),h=P.useCallback(v=>{const N=gs(e);N&&(p.current=N.revision,E(Ve(N.workspace,N.active))),z(!1),c("recovering"),g(v instanceof Error?v.message:"Layout server belum tersambung")},[E,z,e]),M=P.useCallback(()=>R(async()=>{try{j(await $.getTerminalWorkspace())}catch(v){h(v)}}),[j,R,h]);P.useEffect(()=>{const v=++I.current;return c("loading"),g(null),z(!1),R(async()=>{try{const N=await $.getTerminalWorkspace();if(v!==I.current)return;if(N.workspace){j(N),ht();return}const D=fs();if(!D){j(N);return}try{const w=await $.putTerminalWorkspace({baseRevision:N.revision,workspace:D.workspace});if(v!==I.current)return;E(Ve(w.workspace,D.active)),p.current=w.revision,ft(e,{workspace:w.workspace,revision:w.revision,active:D.active}),ht(),c("ready"),g(null),z(!0)}catch(w){const o=gt(w);o!=null&&o.workspace?(j(o,"conflict","Layout server lebih baru; layout lokal lama tidak diunggah"),ht()):h(w)}}catch(N){v===I.current&&h(N)}}),()=>{I.current+=1}},[j,R,h,E,z,e]),P.useEffect(()=>{const v=()=>{M()},N=()=>{document.visibilityState==="visible"&&M()};return window.addEventListener("focus",v),document.addEventListener("visibilitychange",N),()=>{window.removeEventListener("focus",v),document.removeEventListener("visibilitychange",N)}},[M]);const K=P.useCallback(v=>R(async()=>{if(!b.current)return!1;const N=v(k.current);let D,w;try{D=ve(N),w=ve(k.current)}catch{return c("conflict"),g("Layout tidak valid dan tidak disimpan"),!1}if(ba(D,w))return!0;try{return j(await $.putTerminalWorkspace({baseRevision:p.current,workspace:D}),"ready",null,N.active),!0}catch(o){const T=gt(o);if(!(T!=null&&T.workspace))return h(o),!1;const H=v(Ve(T.workspace,k.current.active));try{const L=await $.putTerminalWorkspace({baseRevision:T.revision,workspace:ve(H)});return j(L,"conflict","Layout berubah di perangkat lain; perubahan ini diterapkan ulang",H.active),!0}catch(L){if(!gt(L)&&!(L instanceof ze&&L.status===409))return h(L),!1;try{j(await $.getTerminalWorkspace(),"conflict","Layout berubah lagi di perangkat lain; state terbaru dimuat")}catch(le){h(le)}return!1}}}),[j,R,h]),_=P.useCallback(v=>{const N=ms(k.current,v);E(N);const D=ve(N);ft(e,{workspace:D,revision:p.current,active:N.active})},[E,e]);return{workspace:s,status:l,message:x,writable:S,mutate:K,setActive:_,refresh:M}}const ks=Sn("focus","grid"),ca={attention:0,running:1,open:1,failed:2,done:3};function za(e,n){return e.exited?e.exitCode?{tone:"failed",label:`Gagal · exit ${e.exitCode}`}:{tone:"done",label:"Selesai"}:n?{tone:"done",label:"Selesai"}:e.deciding?{tone:"attention",label:"Lead memutuskan"}:e.decision?{tone:"attention",label:"Menunggu keputusan"}:e.specId?{tone:"running",label:"Berjalan"}:{tone:"open",label:"Terbuka"}}function xs(e){const n=e.startedAt;return typeof n=="number"&&Number.isFinite(n)&&n>0?n*1e3:null}function vs(e,n){const s=e.map((r,l)=>({session:r,index:l,rank:ca[za(r,n.has(r.id)).tone]}));return s.sort((r,l)=>{if(r.rank!==l.rank)return r.rank-l.rank;if(r.rank===ca.attention){const c=r.session.decisionAt?Date.parse(r.session.decisionAt):Number.NaN,x=l.session.decisionAt?Date.parse(l.session.decisionAt):Number.NaN,g=Number.isNaN(c)?Number.POSITIVE_INFINITY:c,S=Number.isNaN(x)?Number.POSITIVE_INFINITY:x;if(g!==S)return g<S?-1:1}return r.index-l.index}),s.map(r=>r.session)}function js(e){const n=new Map;for(const s of e){const r=n.get(s.projectId);r?r.push(s):n.set(s.projectId,[s])}return[...n.values()].flat()}function ys(e,n){if(n){const s=e.find(r=>r.id===n);if(s)return s}return e[0]??null}function ws(e,n,s){if(s<=0)return null;const r=e<0?0:e;switch(n){case"ArrowDown":return Math.min(r+1,s-1);case"ArrowUp":return Math.max(r-1,0);case"Home":return 0;case"End":return s-1;default:return null}}const Aa={attention:"awaiting",running:"running",open:"idle",failed:"failed",done:"done"};function Ss(e){const[n,s]=d.useState(()=>Date.now());return d.useEffect(()=>{const r=setInterval(()=>s(Date.now()),e);return()=>clearInterval(r)},[e]),n}function ua({items:e,focusedId:n,onFocus:s,menuFor:r,label:l="Daftar sesi"}){const c=Ss(3e4),x=d.useRef([]),g=new Set(e.map(k=>k.session.projectId)).size>1,S=e.findIndex(k=>k.session.id===n),f=k=>{var I;const p=x.current.indexOf(k.target);if(p<0)return;const b=ws(p,k.key,e.length);if(b===null)return;k.preventDefault();const y=e[b];y&&(s(y.session.id),(I=x.current[b])==null||I.focus())};return a.jsx("ul",{role:"list","aria-label":l,className:"hn-terminal-rail-list",onKeyDown:f,children:e.map((k,p)=>{var R;const{session:b,status:y}=k,I=b.id===n,E=I||S<0&&p===0,z=k.startedMs!==null?Nn(k.startedMs,c):"";return a.jsxs(d.Fragment,{children:[g&&k.session.projectId!==((R=e[p-1])==null?void 0:R.session.projectId)&&a.jsx("li",{role:"presentation",className:"hn-terminal-rail-group",children:k.projectName}),a.jsx("li",{className:"hn-terminal-rail-item",children:a.jsxs("div",{className:`hn-terminal-rail-row${I?" is-focused":""}`,"data-tone":y.tone,children:[a.jsxs("button",{type:"button",className:"hn-terminal-rail-main",ref:j=>{x.current[p]=j},tabIndex:E?0:-1,"aria-current":I?"true":void 0,title:k.label,onClick:()=>s(b.id),children:[a.jsx("span",{className:"hn-terminal-rail-name",children:k.label}),a.jsxs("span",{className:"hn-terminal-rail-meta",children:[a.jsx(me,{status:Aa[y.tone],variant:"dot",size:"sm",children:y.label}),z&&a.jsx("span",{className:"hn-terminal-rail-time",children:z})]})]}),a.jsx(ye,{label:`Aksi sesi ${b.id} di daftar`,items:r(b)})]})})]},b.id)})})}const Ns=[],Is=e=>!!(e.binding??e.repoDir),Cs=e=>{var n;return((n=e.find(Is)??e[0])==null?void 0:n.id)??""},Ts=e=>e instanceof ze&&e.status===400&&typeof e.detail=="object"&&e.detail!==null&&e.detail.needsBind===!0;function Gs({userId:e="test-user",projects:n,backlog:s=Ns,focusSession:r,startedSession:l,onStartedSessionHandled:c,onStartBacklog:x,onOpenReview:g,onOpenSessionReview:S,titleOf:f,onIntegrate:k,onIntegrateSession:p,specOf:b,sessions:y,setSessions:I,onOpenProject:E}){const[z,R]=d.useState([]),j=y??z,h=I??R,[M,K]=d.useState([]),_=bs(e),{workspace:v,status:N,message:D,writable:w,mutate:o,setActive:T,refresh:H}=_,[L,le]=de("terminal","project",Cs(n),Hn),pe=ka(),we=Rn(),ee=we==="mobile",[W,Me]=de("terminal","fontSize",pe?Gn:Wn,_n),[oe,ie]=de("terminal","keys",pe&&!ee,Ue),[V,Je]=de("terminal","predict",!0,Ue),[J,$e]=de("terminal","diag",!1,Ue),[he,$a]=de("terminal","sr",!1,Ue),Nt=t=>Me(i=>Kn(i+t)),[ce,It]=d.useState(!1),[te,Xe]=d.useState(null),[Fa,Fe]=d.useState(!1),[Pa,Pe]=d.useState(null),[La,Ct]=d.useState(!1),[Oa,Ze]=d.useState(!1),[Ba,Le]=d.useState(!1),[Ka,Qe]=de("terminal","view","focus",ks),q=Ka==="focus",[et,Se]=d.useState(null),[tt,_a]=d.useState(()=>new Set),[Ga,Wa]=d.useState(null),[Tt,Rt]=d.useState(!1),[qa,Et]=d.useState(!1),[Oe,zt]=d.useState(null),at=En(),{confirm:Ua,dialog:Ha}=zn(),A=De(v).layout,nt=A.rows===1&&A.cols===1&&!A.cells[0]&&j.length===0,st=d.useRef(null),[Va,Ya]=d.useState(Number.POSITIVE_INFINITY);d.useEffect(()=>{const t=st.current;if(!t||typeof ResizeObserver!="function")return;const i=new ResizeObserver(u=>{var C;const m=((C=u[0])==null?void 0:C.contentRect.width)??t.getBoundingClientRect().width;m>0&&Ya(m)});return i.observe(t),()=>i.disconnect()},[nt]);const Ja=we==="tablet"&&An(A.cols,Va,Bn),O=ee||Ja,[X,Be]=d.useState(0),[ae,Ke]=d.useState(null),it=d.useRef(null),Ne=t=>{Se(t),Ke(t)},Xa=d.useCallback((t,i)=>{_a(u=>{if(u.has(t)===i)return u;const m=new Set(u);return i?m.add(t):m.delete(t),m})},[]),At=d.useMemo(()=>js(vs(j,tt)),[j,tt]),_e=ys(At,et),Ge=(_e==null?void 0:_e.id)??null;d.useEffect(()=>{Ge&&Ge!==et&&Se(Ge)},[Ge,et]);const[fe,Za]=d.useState(!1),[We,Dt]=d.useState(null),[Qa,en]=d.useState(0);d.useEffect(()=>{let t=!0;return $.listTerminals().then(i=>{t&&(Dt(null),h(i),Za(!0))}).catch(i=>{t&&Dt(ne("memuat daftar sesi",i))}),()=>{t=!1}},[Qa]);const[tn,ge]=Dn();d.useEffect(()=>Mn(t=>{t.t==="sessions"&&!y?h(t.sessions):t.t==="cleanups"&&K(t.cleanups)}),[]),d.useEffect(()=>{if(!fe||!w)return;const t=new Set(j.map(u=>u.id)),i=oa(v,t);ba(ve(i),ve(v))||o(u=>oa(u,t))},[o,j,fe,w,v]),d.useEffect(()=>{!l||l.specId==null||!fe||(h(t=>t.some(i=>i.id===l.id)?t:[...t,{...l,cwd:"",exited:!1}]),Se(l.id),Ke(l.id),c==null||c())},[c,fe,l]);const rt=d.useRef(null);d.useEffect(()=>{if(!r){it.current=null,rt.current=null;return}if(!(!fe||it.current===r)){if(!j.some(t=>t.id===r&&!t.exited)){if(rt.current===r)return;rt.current=r,$.listSessionHistory({q:r,limit:1}).then(t=>ge(Xt,"warn","history",t.total>0?{action:{label:$n,onAction:()=>Le(!0)},duration:7e3}:void 0)).catch(()=>{ge(Xt,"warn","history")});return}it.current=r,Se(r),Ke(r)}},[r,j,fe,ge]),d.useEffect(()=>{if(!ae)return;const t=v.groups.find(i=>i.layout.cells.includes(ae));if(t){t.id!==v.active&&T(t.id);return}w&&o(i=>{if(la(i).has(ae))return i;const u=xe(i,ae);return u!==i||!O?u:vt(i,X,ae)})},[X,O,o,ae,T,w,v]),d.useEffect(()=>{te&&!j.some(t=>t.id===te)&&Xe(null)},[te,j]);const lt=M.filter(t=>t.error),ue=t=>j.find(i=>i.id===t)??null,Z=d.useCallback(t=>{var i;return((i=n.find(u=>u.id===t))==null?void 0:i.name)??t},[n]);function an(t){h(i=>i.some(u=>u.id===t)?i:[...i,{id:t,projectId:L,cwd:"",exited:!1}]),o(i=>xe(i,t)),Ne(t)}async function Mt(t){if(!t)return;Ze(!1);let i;try{({id:i}=await $.createShell(t))}catch(u){Ts(u)?ge(`Project ${Z(t)} belum terhubung ke folder repo — hubungkan dulu.`,"err","folder-git-2",E?{action:{label:"Buka project",onAction:()=>E(t)}}:void 0):ge(ne("membuka terminal biasa",u),"err","x-circle");return}h(u=>[...u,{id:i,projectId:t,cwd:"",exited:!1}]),o(u=>xe(u,i)),Ne(i)}async function $t(t,i){if(x&&!i){Fe(!1),Pe(null),x(t);return}const u=Un(t.source);try{const{id:m}=await $.startSession({spec:t.id,flow:u,...i?{force:i}:{}});h(C=>C.some(F=>F.id===m)?C:[...C,{id:m,projectId:t.projectId,specId:t.id,flow:u,cwd:"",exited:!1}]),o(C=>xe(C,m)),Ne(m),Fe(!1),Pe(null)}catch(m){if(at.offerRetry(m,t.id,F=>$t(t,F)))return;const C=m instanceof ze&&(m.status===400||m.status===422);Pe(`${t.id} · gagal mulai${C?" · project belum punya repoDir":""}`)}}async function Ft(t,i){try{const u=t.specId?await $.startSession({spec:t.specId,flow:t.flow??"feature",agent:t.agent==="codex"?"codex":"claude",...t.model?{model:t.model}:{},...t.effort?{effort:t.effort}:{},...i?{force:i}:{}}):t.kind==="shell"?await $.createShell(t.projectId):t.kind==="terminal"?await $.createTerminal(t.projectId,{agent:t.agent==="codex"?"codex":"claude",...t.model?{model:t.model}:{},...t.effort?{effort:t.effort}:{}}):await(i?$.createTerminalFlow(t.projectId,t.kind,{force:i}):$.createTerminalFlow(t.projectId,t.kind));h(m=>m.some(C=>C.id===u.id)?m:[...m,{id:u.id,projectId:t.projectId,specId:t.specId??void 0,cwd:"",exited:!1}]),o(m=>xe(m,u.id)),Ne(u.id),Le(!1)}catch(u){if((t.specId||t.kind!=="shell"&&t.kind!=="terminal")&&at.offerRetry(u,`${t.projectId} · ${t.title??t.specId??t.kind}`,m=>Ft(t,m)))return}}const Pt=new Set(j.filter(t=>t.specId&&!t.exited).map(t=>t.specId)),nn=s.filter(t=>t.stage!=="done"&&!Pt.has(t.id));function Lt(t){h(i=>i.filter(u=>u.id!==t)),$.deleteTerminal(t).catch(i=>{i instanceof ze&&i.status===404||ge(ne(`menutup sesi ${t.slice(0,6)}`,i),"err","x-circle")})}async function ot(t){const i=ue(t),u=`${i?je(i,Z,f):t} · ${t.slice(0,6)}`,m=!!i&&!i.exited;await Ua({title:`Tutup sesi "${u}"?`,impact:[m?"Agen yang sedang berjalan di sesi ini akan dihentikan.":"Sesi ini sudah berhenti, jadi tidak ada agen yang perlu dihentikan.","Worktree sesi ini ikut dibersihkan dari disk."],confirmLabel:"Tutup sesi",icon:"square",tone:"danger"})&&Lt(t)}const sn=d.useCallback((t,i)=>{h(u=>u.map(m=>m.id===t?{...m,exited:!0,exitCode:i}:m))},[]),Ot={killSession:Lt,requestKill:ot,detach:t=>{o(i=>ps(i,t))},markExited:sn,setFullId:Xe,openDialog:(t,i)=>zt({kind:t,sessionId:i}),props:{onOpenReview:g,onOpenSessionReview:S,titleOf:f,onIntegrate:k,onIntegrateSession:p,specOf:b}},G=d.useRef(Ot);G.current=Ot;const Bt=d.useRef(new Map),be=t=>{let i=Bt.current.get(t);return i||(i={onClose:()=>void G.current.requestKill(t),onForget:()=>G.current.killSession(t),onDetach:()=>G.current.detach(t),onExit:u=>G.current.markExited(t,u),onFullscreen:()=>G.current.setFullId(t),onDialog:u=>G.current.openDialog(u,t)},Bt.current.set(t,i)),i},Kt=d.useRef(new Map),rn=t=>{let i=Kt.current.get(t);return i||(i=(u,m)=>{Wa({sessionId:t,phases:u}),Xa(t,m)},Kt.current.set(t,i)),i},ln=t=>Ma(t,{label:je(t,Z,f),canArrange:w,specOf:b,onReview:g,onSessionReview:S,onIntegrate:k,onIntegrateSession:p,onDialog:be(t.id).onDialog,onDetach:be(t.id).onDetach,onFullscreen:be(t.id).onFullscreen,onKill:()=>void ot(t.id)}),ke=d.useRef({onOpenReview:t=>{var i,u;return(u=(i=G.current.props).onOpenReview)==null?void 0:u.call(i,t)},onOpenSessionReview:(t,i)=>{var u,m;return(m=(u=G.current.props).onOpenSessionReview)==null?void 0:m.call(u,t,i)},titleOf:t=>{var i,u;return(u=(i=G.current.props).titleOf)==null?void 0:u.call(i,t)},onIntegrate:(t,i,u)=>{var m,C;return(C=(m=G.current.props).onIntegrate)==null?void 0:C.call(m,t,i,u)},onIntegrateSession:(t,i,u)=>{var m,C;return(C=(m=G.current.props).onIntegrateSession)==null?void 0:C.call(m,t,i,u)},specOf:t=>{var i,u;return(u=(i=G.current.props).specOf)==null?void 0:u.call(i,t)}}).current,on=(t,i)=>{Be(t),o(u=>vt(u,t,i))},cn=t=>{Ne(t),o(i=>xe(i,t))},un=la(v),ct=j.filter(t=>!un.has(t.id));d.useEffect(()=>{if(!ae)return;const t=A.cells.indexOf(ae);t<0||(Be(t),Ke(null))},[A.cells,ae]),d.useEffect(()=>{X>=A.cells.length&&Be(Math.max(0,A.cells.length-1))},[X,A.cells.length]);const qe=d.useRef(null),[re,ut]=d.useState(null),dt=(re==null?void 0:re.axis)==="col"?re.sizes:A.colSizes??Array(A.cols).fill(1),mt=(re==null?void 0:re.axis)==="row"?re.sizes:A.rowSizes??Array(A.rows).fill(1);function _t(t,i,u){var F,Y,Ie;if(!w)return;const m=(F=st.current)==null?void 0:F.getBoundingClientRect();if(!m)return;(Ie=(Y=u.currentTarget).setPointerCapture)==null||Ie.call(Y,u.pointerId);const C=t==="col"?dt:mt;qe.current={axis:t,index:i,pointerId:u.pointerId,start:t==="col"?u.clientX:u.clientY,extent:t==="col"?m.width:m.height,startSizes:C,latest:C},ut({axis:t,sizes:C})}function Gt(t){const i=qe.current;if(!i||i.pointerId!==t.pointerId)return;const u=i.axis==="col"?t.clientX:t.clientY,m=i.startSizes.reduce((F,Y)=>F+Y,0),C=(u-i.start)/i.extent*m;i.latest=wt(i.startSizes,i.index,C),ut({axis:i.axis,sizes:i.latest})}function Wt(t){var u,m;const i=qe.current;!i||i.pointerId!==t.pointerId||(qe.current=null,(m=(u=t.currentTarget).releasePointerCapture)==null||m.call(u,t.pointerId),ut(null),i.latest!==i.startSizes&&o(C=>U(C,F=>i.axis==="col"?{...F,colSizes:i.latest}:{...F,rowSizes:i.latest})))}function qt(t,i,u){if(!w)return;const m=t==="col"?"ArrowRight":"ArrowDown",C=t==="col"?"ArrowLeft":"ArrowUp",F=u.key===m?1:u.key===C?-1:0;F!==0&&(u.preventDefault(),o(Y=>U(Y,Ie=>t==="col"?rs(Ie,i,F,u.shiftKey):ls(Ie,i,F,u.shiftKey))))}function Ut(t,i){w&&o(u=>U(u,m=>{const C=t==="col"?m.colSizes??Array(m.cols).fill(1):m.rowSizes??Array(m.rows).fill(1),Y=(C[i]+C[i+1])/2-C[i];return t==="col"?Sa(m,i,Y):Na(m,i,Y)}))}const Ht=a.jsxs("div",{className:"hn-terminal-display",children:[a.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[a.jsx("span",{className:"hn-terminal-display-label",children:"Ukuran teks terminal"}),a.jsx(pt,{size:"sm",icon:"minus",label:"Perkecil teks terminal",disabled:W<=Fn,onClick:()=>Nt(-1)}),a.jsxs("span",{className:"hn-terminal-display-value",children:[W,"px"]}),a.jsx(pt,{size:"sm",icon:"plus",label:"Perbesar teks terminal",disabled:W>=Pn,onClick:()=>Nt(1)})]}),a.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[a.jsx("span",{className:"hn-terminal-display-label",children:"Papan tombol layar (Esc · panah · Enter)"}),a.jsx(B,{size:"sm",variant:"secondary","aria-pressed":oe,onClick:()=>ie(t=>!t),children:oe?"Sembunyikan":"Tampilkan"})]}),a.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[a.jsx("span",{className:"hn-terminal-display-label",children:"Ketik responsif (huruf tampil sebelum echo server)"}),a.jsx(B,{size:"sm",variant:"secondary","aria-pressed":V,"aria-label":`${V?"Matikan":"Nyalakan"} ketik responsif`,onClick:()=>Je(t=>!t),children:V?"Matikan":"Nyalakan"})]}),a.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[a.jsx("span",{id:"terminal-sr-label",className:"hn-terminal-display-label",children:"Mode pembaca layar"}),a.jsx(B,{size:"sm",variant:"secondary","aria-pressed":he,"aria-describedby":"terminal-sr-hint","aria-label":`${he?"Matikan":"Nyalakan"} mode pembaca layar`,onClick:()=>$a(t=>!t),children:he?"Matikan":"Nyalakan"})]}),a.jsx("p",{id:"terminal-sr-hint",className:"hn-terminal-sr-hint",children:"Untuk pembaca layar: teks terminal tersedia di DOM; kecepatan lebih rendah. Tab dikirim ke sesi (tidak memindahkan fokus). Untuk keluar dari terminal tekan Ctrl+Shift+Esc."}),!q&&a.jsxs("div",{className:"hn-dense-row hn-terminal-display-row",children:[a.jsx("span",{id:"terminal-reset-grid-hint",className:"hn-terminal-display-label",children:'Kembalikan grid ke 1 kolom × 1 baris (sesi lain pindah ke "belum di grid")'}),a.jsx(B,{size:"sm",variant:"secondary","aria-describedby":"terminal-reset-grid-hint",disabled:!w||A.cols===1&&A.rows===1,onClick:()=>void o(t=>U(t,()=>ja())),children:"Reset grid"})]}),a.jsxs("details",{className:"hn-terminal-diag",children:[a.jsxs("summary",{className:"hn-terminal-diag-summary",children:["Diagnostik",J?" · perekaman aktif":""]}),a.jsxs("div",{className:"hn-dense-row hn-terminal-display-row hn-terminal-diag-row",children:[a.jsx("span",{className:"hn-terminal-display-label",children:"Rekam jalur ketik — mencatat setiap tombol yang ditekan di pane. Nyalakan hanya saat menyelidiki masalah ketik."}),a.jsx(B,{size:"sm",variant:"secondary","aria-pressed":J,"aria-label":`${J?"Matikan":"Nyalakan"} rekam jalur ketik`,onClick:()=>$e(t=>!t),children:J?"Matikan":"Nyalakan"})]})]})]}),Vt=[{key:"backlog",label:"Ambil backlog",icon:"inbox",onSelect:()=>{Pe(null),Fe(!0)}},{key:"history",label:"Riwayat sesi",icon:"history",onSelect:()=>Le(!0)},{key:"shell",label:"Terminal biasa",icon:"terminal",onSelect:()=>n.length>1?Ze(!0):void Mt(L)}],dn=[{key:"col+",label:"+ Kolom",icon:"columns-2",disabled:!w,onSelect:()=>void o(t=>U(t,aa))},{key:"row+",label:"+ Baris",icon:"rows-2",disabled:!w,onSelect:()=>void o(t=>U(t,ta))},{key:"col-",label:"Hapus kolom aktif",icon:"columns-2",disabled:!w||A.cols===1,onSelect:()=>void o(t=>U(t,i=>sa(i,X%i.cols)))},{key:"row-",label:"Hapus baris aktif",icon:"rows-2",disabled:!w||A.rows===1,onSelect:()=>void o(t=>U(t,i=>na(i,Math.floor(X/i.cols))))}],mn=[{key:"mode",label:q?"Pakai mode Grid":"Pakai mode Fokus",icon:q?"columns-2":"terminal",onSelect:()=>Qe(q?"grid":"focus")},{key:"full",label:ce?"Keluar layar penuh":"Layar penuh",icon:ce?"minimize-2":"maximize-2",onSelect:()=>It(t=>!t)},{key:"display",label:"Tampilan terminal",icon:"sliders",onSelect:()=>Et(!0)}];return a.jsxs("div",{"data-testid":"terminal-root",className:ce?"hn-terminal-screen is-maxed":"hn-terminal-screen",children:[a.jsxs("div",{className:"hn-terminal-toolbar",role:"group","aria-label":"Terminal",children:[a.jsx(B,{size:"sm",leftIcon:"plus",title:"Pilih runtime lalu buka sesi agen di direktori project. Agen berjalan dengan izin penuh (claude --dangerously-skip-permissions).",onClick:()=>Ct(!0),children:"Sesi baru"}),ee?a.jsxs(a.Fragment,{children:[a.jsx(ha,{compact:!0,items:Vt}),q&&j.length>0&&a.jsxs("button",{type:"button",className:"hn-terminal-rail-toggle","aria-haspopup":"dialog","aria-expanded":Tt,onClick:()=>Rt(!0),children:["Sesi · ",j.length]}),a.jsx(ye,{label:"Menu terminal",title:"Terminal",items:mn})]}):a.jsxs(a.Fragment,{children:[a.jsx(ha,{items:Vt}),a.jsxs("div",{className:"hn-terminal-seg",role:"group","aria-label":"Mode tampilan terminal",children:[a.jsx("button",{type:"button",className:"hn-terminal-seg-btn","aria-pressed":q,title:"Satu terminal fokus dengan daftar sesi di samping",onClick:()=>Qe("focus"),children:"Fokus"}),a.jsx("button",{type:"button",className:"hn-terminal-seg-btn","aria-pressed":!q,title:"Beberapa terminal sekaligus dalam grid",onClick:()=>Qe("grid"),children:"Grid"})]}),a.jsx(ye,{label:"Tampilan terminal",icon:"sliders",items:[],children:Ht}),a.jsx(pt,{size:"sm",icon:ce?"minimize-2":"maximize-2",label:ce?"Keluar layar penuh":"Layar penuh","aria-pressed":ce,onClick:()=>It(t=>!t)})]})]}),(N!=="ready"||M.length>0)&&a.jsxs("div",{className:"hn-terminal-status",children:[N!=="ready"&&a.jsx("span",{"data-testid":"terminal-workspace-status",title:D??void 0,className:N==="conflict"?"hn-terminal-status-warn":void 0,children:N==="loading"?"Memuat layout server…":N==="recovering"?a.jsxs(a.Fragment,{children:[a.jsx("span",{children:"Layout server belum tersambung"})," ",a.jsx("button",{type:"button",onClick:()=>void H(),children:"Coba lagi"})]}):D??"Layout berubah di perangkat lain"}),M.length>0&&a.jsx("span",{"data-testid":"worktree-cleanups",title:M.map(t=>`${t.sessionId}${t.error?` — ${t.error}`:""}`).join(`
|
|
2
|
-
`),className:lt.length?"hn-terminal-status-err":void 0,children:lt.length?`${lt.length} worktree gagal dibersihkan`:`membersihkan ${M.length} worktree…`})]}),!q&&a.jsxs("div",{className:"hn-terminal-grid-bar",children:[a.jsx(Es,{compact:ce,ws:v,writable:w,onSelect:T,onAdd:()=>void o(t=>cs(t,`Grup ${t.groups.length+1}`)),onRename:(t,i)=>void o(u=>us(u,t,i)),onRemove:t=>void o(i=>ds(i,t))}),!O&&a.jsxs(a.Fragment,{children:[a.jsx(B,{size:"sm",variant:"ghost",disabled:!w,onClick:()=>void o(t=>U(t,aa)),children:"+ Kolom"}),a.jsx(B,{size:"sm",variant:"ghost",disabled:!w,onClick:()=>void o(t=>U(t,ta)),children:"+ Baris"})]}),O&&a.jsx(ye,{label:"Atur grid",icon:"sliders",items:dn})]}),We&&a.jsxs(Ye,{tone:"err",title:"Daftar sesi belum bisa dimuat",className:"hn-terminal-notice--tight",children:[a.jsxs("span",{children:[We," "]}),a.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>en(t=>t+1),children:"Coba lagi"})]}),!q&&ct.length>0&&a.jsxs("div",{className:"hn-terminal-unplaced",children:[a.jsx("span",{className:"hn-terminal-unplaced-label",children:"Belum di grid:"}),ct.map(t=>a.jsxs("span",{className:"hn-terminal-unplaced-chip",children:[a.jsxs("button",{className:"hn-terminal-unplaced-action",disabled:!w,onClick:()=>cn(t.id),title:"Taruh di sel kosong pertama grup ini",children:[t.specId??Z(t.projectId)," · ",t.id.slice(0,6)]}),a.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${t.id}`,onClick:()=>void ot(t.id),children:"×"})]},t.id))]}),!q&&O&&!nt&&a.jsx("div",{className:"hn-stack-mobile hn-terminal-tabs-row",children:a.jsx(Ln,{"aria-label":"Panel terminal",variant:"pill",value:String(X),onChange:t=>Be(Number(t)),tabs:A.cells.map((t,i)=>({value:String(i),label:`Panel ${i+1}${t?` · ${t.slice(0,6)}`:" · kosong"}`}))})}),!q&&(nt?We?null:a.jsx(Re,{kind:"empty",icon:"terminal",title:"Belum ada sesi terminal",hint:"Tekan Sesi baru untuk memulai agen di project terpilih, atau Terminal biasa untuk shell."}):a.jsxs("div",{ref:st,"data-testid":"terminal-grid",className:"hn-terminal-grid",style:{"--grid-cols":O?"minmax(0, 1fr)":`18px ${dt.map(t=>`minmax(0, ${t}fr)`).join(" ")}`,"--grid-rows":O?"minmax(0, 1fr)":`16px ${mt.map(t=>`minmax(0, ${t}fr)`).join(" ")}`},children:[!O&&a.jsx("div",{className:"hn-terminal-grid-corner"}),!O&&Array.from({length:A.cols},(t,i)=>a.jsx(da,{axis:"col",label:`Tutup kolom ${i+1}`,disabled:!w||A.cols===1,gridColumn:i+2,gridRow:1,onClick:()=>void o(u=>U(u,m=>sa(m,i)))},`col-${i}`)),!O&&Array.from({length:A.rows},(t,i)=>a.jsx(da,{axis:"row",label:`Tutup baris ${i+1}`,disabled:!w||A.rows===1,gridColumn:1,gridRow:i+2,onClick:()=>void o(u=>U(u,m=>na(m,i)))},`row-${i}`)),!O&&Array.from({length:A.cols-1},(t,i)=>{const u=ia(dt,i);return a.jsx(ma,{orientation:"col",label:`Ubah lebar kolom ${i+1}/${i+2}`,now:u.now,min:u.min,max:u.max,disabled:!w,gridColumn:i+3,gridRow:"1 / -1",onPointerDown:m=>_t("col",i,m),onPointerMove:Gt,onPointerUp:Wt,onKeyDown:m=>qt("col",i,m),onDoubleClick:()=>Ut("col",i)},`col-div-${i}`)}),!O&&Array.from({length:A.rows-1},(t,i)=>{const u=ia(mt,i);return a.jsx(ma,{orientation:"row",label:`Ubah tinggi baris ${i+1}/${i+2}`,now:u.now,min:u.min,max:u.max,disabled:!w,gridColumn:"1 / -1",gridRow:i+3,onPointerDown:m=>_t("row",i,m),onPointerMove:Gt,onPointerUp:Wt,onKeyDown:m=>qt("row",i,m),onDoubleClick:()=>Ut("row",i)},`row-div-${i}`)}),Array.from({length:A.rows},(t,i)=>i).flatMap(t=>Array.from({length:A.cols},(i,u)=>{const m=t*A.cols+u,C=A.cells[m]??null,F=C?ue(C):null;return a.jsx("div",{"data-terminal-cell-index":m,"aria-hidden":O&&X!==m?"true":"false",className:O&&X!==m?"hn-terminal-cell-slot is-hidden":"hn-terminal-cell-slot",style:{"--cell-col":O?"auto":u+2,"--cell-row":O?"auto":t+2},children:F?a.jsx(Ds,{session:F,nameOf:Z,...be(F.id),canArrange:w,onReview:g&&ke.onOpenReview,onSessionReview:S&&ke.onOpenSessionReview,titleOf:f&&ke.titleOf,onIntegrate:k&&ke.onIntegrate,onIntegrateSession:p&&ke.onIntegrateSession,specOf:b&&ke.specOf,backlog:s,fontSize:W,showKeys:oe,predict:V,diag:J,screenReader:he,fullscreen:te===F.id,paneHidden:O&&X!==m}):a.jsx(Ls,{disabled:!w,unplaced:ct,nameOf:Z,onPick:Y=>on(m,Y)})},C??`empty-${m}`)}))]})),q&&a.jsx(Fs,{sessionCount:j.length,focused:_e,mobile:ee,railItems:At.map(t=>({session:t,label:je(t,Z,f),projectName:Z(t.projectId),status:za(t,tt.has(t.id)),startedMs:xs(t)})),listError:!!We,menuFor:ln,onFocus:Se,drawerOpen:Tt,onDrawer:Rt,fullId:te,focusPhases:Ga,paneHandlers:t=>({onExit:be(t).onExit,onPhases:rn(t),onForget:be(t).onForget}),fontSize:W,showKeys:oe,onToggleKeys:()=>ie(t=>!t),predict:V,diag:J,screenReader:he}),Fa&&a.jsx(Rs,{seed:nn,activeIds:Pt,error:Pa,onPick:t=>void $t(t),onClose:()=>Fe(!1)}),La&&a.jsx(ts,{open:!0,projectId:L,projectName:Z(L),projects:n,onProjectChange:le,onClose:()=>Ct(!1),onCreated:an}),Oa&&a.jsx(as,{projectId:L,projects:n,onProjectChange:le,onClose:()=>Ze(!1),onConfirm:t=>void Mt(t)}),Ba&&a.jsx(Qn,{projects:n,onClose:()=>Le(!1),onRestart:t=>void Ft(t)}),at.dialog,Oe&&ue(Oe.sessionId)&&a.jsx($s,{kind:Oe.kind,session:ue(Oe.sessionId),specOf:b,onIntegrate:k,onIntegrateSession:p,onClose:()=>zt(null)}),te&&ue(te)&&a.jsx(Ps,{session:ue(te),label:je(ue(te),Z,f),fontSize:W,showKeys:oe,predict:V,diag:J,screenReader:he,onClose:()=>Xe(null)}),ee&&qa&&a.jsx(se,{open:!0,title:"Tampilan terminal",icon:"sliders",width:420,onClose:()=>Et(!1),children:Ht}),Ha,a.jsx(On,{toast:tn})]})}function je(e,n,s){const r=n(e.projectId),l=e.specId?s==null?void 0:s(e.specId):void 0;return e.specId?`${r} · ${e.specId}${l?` · ${l}`:""}`:e.id.startsWith("xaudit-")?`${r} · audit lintas`:r}function Rs({seed:e,activeIds:n,error:s,onPick:r,onClose:l}){const[c,x]=d.useState(""),[g,S]=d.useState("all"),[f,k]=d.useState("all"),[p,b]=d.useState(e),[y,I]=d.useState(""),[E,z]=d.useState(null);d.useEffect(()=>{const h=setTimeout(()=>I(c.trim()),250);return()=>clearTimeout(h)},[c]),d.useEffect(()=>{var K,_;let h=!0;const M=(_=(K=$).listSpecs)==null?void 0:_.call(K,{startable:!0,q:y||void 0,stage:g==="all"?void 0:g,priority:f==="all"?void 0:f});return M==null||M.then(v=>{h&&(b(v.items),z(null))}).catch(v=>{h&&z(ne("memuat backlog",v))}),()=>{h=!1}},[y,g,f]);const R=p.filter(h=>!n.has(h.id)),j=s??E;return a.jsxs(se,{open:!0,title:"Ambil backlog",icon:"inbox",onClose:l,width:760,children:[j&&a.jsx("div",{role:"alert",className:"hn-terminal-pick-notice",children:j}),a.jsxs("div",{className:"hn-terminal-pick-filters",children:[a.jsx(fa,{size:"sm",leftIcon:"search",placeholder:"mis. invoice atau SPEC-412","aria-label":"Cari backlog",value:c,onChange:h=>x(h.target.value),className:"hn-terminal-pick-search"}),a.jsx(Q,{size:"sm","aria-label":"Filter stage",value:g,onChange:h=>S(h.target.value),options:[{value:"all",label:"Semua stage"}].concat(qn.filter(h=>h.key!=="done").map(h=>({value:h.key,label:h.label})))}),a.jsx(Q,{size:"sm","aria-label":"Filter prioritas",value:f,onChange:h=>k(h.target.value),options:[{value:"all",label:"Semua prioritas"},{value:"tinggi",label:"Tinggi"},{value:"sedang",label:"Sedang"},{value:"rendah",label:"Rendah"}]})]}),R.length===0?a.jsx(Re,{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",{className:"hn-terminal-pick-list",children:R.map(h=>a.jsx("button",{onClick:()=>r(h),className:"hn-terminal-pick-row",children:a.jsxs("span",{className:"hn-dense-row hn-picker-row hn-terminal-pick-main",children:[a.jsx(Ee,{name:h.source==="qa"?"bug":h.source==="audit"?"search":"lightbulb",size:14,color:h.source==="qa"?"var(--clay-500)":h.source==="audit"?"var(--wind-600)":"var(--brass-500)"}),a.jsx("span",{className:"hn-terminal-pick-id",children:h.id}),a.jsx("span",{className:"hn-picker-title hn-terminal-pick-title",children:h.title}),a.jsx(bt,{tone:h.priority==="tinggi"?"err":"neutral",size:"sm",children:h.priority}),a.jsx("span",{className:"hn-terminal-pick-project",children:h.projectId})]})},h.id))})]})}function Es({ws:e,compact:n=!1,writable:s,onSelect:r,onAdd:l,onRename:c,onRemove:x}){const[g,S]=d.useState(null),f=De(e),k=e.groups.length===1,b=ka()?44:24;return a.jsxs("div",{className:n?"hn-terminal-groups":"hn-terminal-groups is-bordered",style:{"--group-box":`${b}px`},children:[a.jsx("div",{role:"tablist","aria-label":"Grup terminal",className:"hn-terminal-groups-tabs",children:e.groups.map((y,I)=>{const E=y.id===f.id;return a.jsx("button",{type:"button",role:"tab","aria-selected":E,tabIndex:E?0:-1,className:"hn-terminal-group-control hn-terminal-group-tab",onClick:()=>r(y.id),onKeyDown:z=>{var j,h;let R=null;z.key==="ArrowRight"?R=(I+1)%e.groups.length:z.key==="ArrowLeft"?R=(I-1+e.groups.length)%e.groups.length:z.key==="Home"?R=0:z.key==="End"&&(R=e.groups.length-1),R!==null&&(z.preventDefault(),r(e.groups[R].id),(h=(j=z.currentTarget.closest('[role="tablist"]'))==null?void 0:j.querySelectorAll('[role="tab"]')[R])==null||h.focus())},children:y.name},y.id)})}),s&&(g===f.id?a.jsx(zs,{initial:f.name,onCommit:y=>{y.trim()&&c(f.id,y.trim()),S(null)},onCancel:()=>S(null)},f.id):a.jsxs("span",{role:"group","aria-label":`Kelola grup ${f.name}`,className:"hn-terminal-groups-actions",children:[a.jsx("button",{type:"button",className:"hn-terminal-group-control hn-terminal-group-action","aria-label":`Ganti nama grup ${f.name}`,title:"Ganti nama",onClick:()=>S(f.id),children:"✎"}),a.jsx("button",{type:"button",className:"hn-terminal-group-control hn-terminal-group-action hn-terminal-group-remove","aria-label":`Hapus grup ${f.name}`,title:k?"Grup terakhir tak bisa dihapus":"Hapus grup (sesi tetap hidup)",disabled:k,onClick:()=>x(f.id),children:"×"})]})),a.jsx("button",{type:"button",className:"hn-terminal-group-control hn-terminal-group-action hn-terminal-group-add","aria-label":"Grup baru",title:"Grup baru",disabled:!s,onClick:l,children:"+"})]})}function da({label:e,disabled:n,onClick:s,axis:r,gridColumn:l,gridRow:c}){return a.jsx("button",{type:"button","aria-label":e,title:n?"Grid tak boleh menyusut ke nol":e,disabled:n,onClick:s,className:`hn-terminal-gutter hn-terminal-gutter--${r}`,style:{"--grid-col":l,"--grid-row":c},children:"×"})}function ma({orientation:e,label:n,now:s,min:r,max:l,disabled:c,gridColumn:x,gridRow:g,onPointerDown:S,onPointerMove:f,onPointerUp:k,onKeyDown:p,onDoubleClick:b}){return a.jsx("div",{role:"separator","aria-label":n,"aria-disabled":c,"aria-orientation":e==="col"?"vertical":"horizontal","aria-valuenow":s,"aria-valuemin":r,"aria-valuemax":l,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:{"--grid-col":x,"--grid-row":g},onPointerDown:c?void 0:S,onPointerMove:c?void 0:f,onPointerUp:c?void 0:k,onPointerCancel:c?void 0:k,onKeyDown:c?void 0:p,onDoubleClick:c?void 0:b})}function zs({initial:e,onCommit:n,onCancel:s}){const[r,l]=d.useState(e);return a.jsx("input",{autoFocus:!0,"aria-label":"Nama grup",value:r,placeholder:"mis. Rilis",onChange:c=>l(c.target.value),onBlur:()=>n(r),onKeyDown:c=>{c.key==="Enter"?n(r):c.key==="Escape"&&s()},className:"hn-terminal-rename"})}const As={done:"✓",running:"●",pending:"○",skipped:"–",failed:"✕",abandoned:"⨯"};function Da({phases:e,compact:n=!1,now:s}){const[r,l]=d.useState(null),c=In(r!==null,()=>l(null),"dialog"),[,x]=d.useState(0),g=!!(e!=null&&e.some(p=>{var b;return((b=p.agent)==null?void 0:b.status)==="running"}));if(d.useEffect(()=>{if(!(!g||s!==void 0))return Jn(()=>x(p=>p+1))},[g,s]),!(e!=null&&e.length))return null;const S=s??Date.now(),f=e.find(p=>p.name===r&&p.agent),k=p=>{const b=p.agent;return b?typeof b.durationMs=="number"?Zt(b.durationMs):b.status==="running"&&b.startedAt?Zt(S-Date.parse(b.startedAt)):"":""};return a.jsxs("div",{"data-testid":"phase-strip",className:"hn-terminal-phase",children:[a.jsx("div",{"data-testid":"phase-strip-scroller",className:"hn-terminal-phase-scroller",children:e.map(p=>{if(!p.agent)return a.jsx("span",{"data-state":p.state,title:p.state,className:"hn-terminal-phase-name",children:p.name},p.name);const b=p.agent,y=Cn(p),I=!n||p.state==="active",E=k(p);return a.jsxs("button",{type:"button","data-tone":y,"aria-expanded":r===p.name,ref:r===p.name?c.triggerRef:void 0,"aria-haspopup":"dialog","aria-controls":r===p.name?c.panelId:void 0,"aria-label":Tn(p,E),onClick:()=>l(r===p.name?null:p.name),className:"hn-terminal-phase-chip",children:[a.jsx("span",{"aria-hidden":!0,children:As[y]}),a.jsx("span",{"data-state":p.state,title:p.state,className:"hn-terminal-phase-name",children:p.name}),p.state==="skipped"&&a.jsx("span",{children:"dilewati"}),I&&b.model&&a.jsxs("span",{children:["· ",kt(b.model)]}),I&&b.effort&&a.jsxs("span",{children:["· ",b.effort]}),I&&E&&a.jsxs("span",{children:["· ",E]}),b.attempts>1&&a.jsxs("span",{children:["↻",b.attempts]}),b.evidence==="missing"&&a.jsx("span",{role:"img","aria-label":"bukti subagent tak diterima",title:"bukti subagent tak diterima",className:"hn-terminal-phase-warn",children:"⚠"})]},p.name)})}),(f==null?void 0:f.agent)&&a.jsxs("div",{ref:c.panelRef,id:c.panelId,role:"dialog","aria-label":`Detail fase ${f.name}`,tabIndex:-1,onKeyDown:c.onKeyDown,className:"hn-terminal-phase-panel",children:[a.jsx("div",{children:a.jsx("b",{children:f.agent.name})}),a.jsx("div",{children:[kt(f.agent.model),f.agent.effort,f.agent.status??"belum mulai"].filter(Boolean).join(" · ")}),a.jsxs("div",{children:["durasi ",k(f)||"—"," · percobaan ",f.agent.attempts]}),a.jsxs("div",{children:["token in ",f.agent.inputTokens??"—"," · out ",f.agent.outputTokens??"—"," · cache ",f.agent.cachedTokens??"—"]}),f.agent.resultExcerpt&&a.jsx("pre",{className:"hn-terminal-phase-excerpt",children:f.agent.resultExcerpt})]})]})}const Ds=d.memo(Ms);function Ms({session:e,nameOf:n,onClose:s,onForget:r,canArrange:l,onDetach:c,onExit:x,onReview:g,onSessionReview:S,titleOf:f,onIntegrate:k,onIntegrateSession:p,specOf:b,fontSize:y,showKeys:I,predict:E,diag:z,screenReader:R,fullscreen:j,onFullscreen:h,onDialog:M,paneHidden:K}){const[_,v]=d.useState(null),N=d.useRef(null),[D,w]=d.useState(Number.POSITIVE_INFINITY);d.useEffect(()=>{const ie=N.current;if(!ie||typeof ResizeObserver!="function")return;const V=new ResizeObserver(Je=>{var $e;const J=(($e=Je[0])==null?void 0:$e.contentRect.width)??ie.getBoundingClientRect().width;J>0&&w(J)});return V.observe(ie),()=>V.disconnect()},[]);const[o,T]=d.useState(!1),H=d.useCallback((ie,V)=>{v(ie),T(V)},[]),L=je(e,n,f),le=!e.exited&&!!e.decision,pe=!e.exited&&!!e.deciding,we=le||pe,ee=e.exited&&!!e.exitCode,W=!e.exited&&o,Me=ee?null:e.exited||W?"PST-005":we?"PST-004":"PST-003",oe=Ma(e,{label:L,canArrange:l,specOf:b,onReview:g,onSessionReview:S,onIntegrate:k,onIntegrateSession:p,onDialog:M,onDetach:c,onFullscreen:h});return a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:e.exited?"hn-terminal-cell-header is-exited":"hn-terminal-cell-header","data-cell-tone":ee?"failed":e.exited||W?"done":we?"attention":"idle",children:[Me&&a.jsx("span",{className:"hn-terminal-cell-illus",children:a.jsx(Yn,{id:Me,decorative:!0})}),a.jsxs("span",{className:"hn-terminal-cell-title",children:[L," · ",e.id.slice(0,6)]}),e.orchestrated&&e.model&&a.jsxs("span",{"data-testid":"orchestrator-chip",title:"Model & effort orchestrator",className:"hn-terminal-orch",children:["orch ",kt(e.model),e.effort?` · ${e.effort}`:""]}),e.exited&&(ee?a.jsx(me,{status:"failed",size:"sm",children:`Gagal · exit ${e.exitCode}`}):a.jsx(me,{status:"done",size:"sm",children:"Selesai"})),W&&a.jsx(me,{status:"done",size:"sm",children:"Selesai"}),pe&&!W&&a.jsx(me,{status:"running",size:"sm",children:"Lead memutuskan"}),le&&!pe&&!W&&a.jsx(me,{status:"awaiting",size:"sm"}),a.jsxs("span",{className:"hn-terminal-actions",children:[a.jsx(ye,{label:`Aksi sesi ${e.id}`,items:oe}),a.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${e.id}`,title:"Tutup sesi (dikonfirmasi dulu)",onClick:s,children:a.jsx(Ee,{name:"x",size:12})})]})]}),a.jsxs("div",{ref:N,className:"hn-terminal-cell-body",children:[e.exited&&a.jsx(St,{}),a.jsx(Da,{phases:_,compact:D<480}),a.jsx("div",{className:"hn-terminal-cell-pane",children:j?a.jsx("div",{className:"hn-terminal-cell-fullscreen",children:"Terbuka di layar penuh"}):a.jsx(jt,{sessionId:e.id,onExit:x,onPhases:H,fontSize:y,showKeys:I,predict:E,diag:z,screenReader:R,hidden:K,onForget:r,label:je(e,n,f)},e.id)})]})]})}function Ma(e,n){var x;const s=[],r=e.specId?(x=n.specOf)==null?void 0:x.call(n,e.specId):void 0,l=!e.specId&&!!e.branch;e.specId&&s.push({key:"docs",label:"Lihat dokumen",icon:"file-text",title:"Lihat dokumen (audit/spec/plan)",onSelect:()=>n.onDialog("docs")});const c=e.specId;if(c&&n.onReview){const g=n.onReview;s.push({key:"review",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree)",onSelect:()=>g(c)})}if(l&&n.onSessionReview){const g=n.onSessionReview;s.push({key:"review-session",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree sesi)",onSelect:()=>g(e.id,n.label)})}return r&&n.onIntegrate&&s.push({key:"integrate",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch spec",onSelect:()=>n.onDialog("integrate")}),l&&n.onIntegrateSession&&s.push({key:"integrate-session",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch sesi",onSelect:()=>n.onDialog("sessIntegrate")}),s.push({key:"detach",label:"Lepas dari grid",icon:"unlink",disabled:!n.canArrange,title:"Lepas dari grid (sesi tetap hidup)",onSelect:n.onDetach}),s.push({key:"fullscreen",label:"Layar penuh",icon:"fullscreen",title:"Layar penuh — fokus 1 terminal",onSelect:n.onFullscreen}),n.onKill&&s.push({key:"close",label:"Tutup sesi",icon:"square",tone:"danger",title:"Tutup sesi (dikonfirmasi dulu)",onSelect:n.onKill}),s}function $s({kind:e,session:n,specOf:s,onIntegrate:r,onIntegrateSession:l,onClose:c}){if(e==="docs")return n.specId?a.jsx(Vn,{specId:n.specId,onClose:c}):null;if(e==="integrate"){const x=n.specId?s==null?void 0:s(n.specId):void 0;return!x||!r?null:a.jsx(Qt,{projectId:x.projectId,ownBranch:`hanoman/${x.id.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,eyebrow:x.id,onClose:c,onIntegrate:(g,S)=>{c(),r(x,g,S)}})}return!n.branch||n.specId||!l?null:a.jsx(Qt,{projectId:n.projectId,ownBranch:n.branch,eyebrow:n.id.slice(0,16),onClose:c,onIntegrate:(x,g)=>{c(),l(n,x,g)}})}const pa="Buka sesi lain: ambil backlog, riwayat sesi, atau terminal biasa";function ha({items:e,compact:n=!1}){const[s,r]=d.useState(!1);return a.jsxs(a.Fragment,{children:[n?a.jsxs("button",{type:"button",className:"hn-terminal-open-compact","aria-label":"Buka…",title:pa,"aria-haspopup":"dialog","aria-expanded":s,onClick:()=>r(!0),children:[a.jsx(Ee,{name:"folder-open",size:16}),a.jsx("span",{className:"hn-terminal-open-text",children:"Buka…"})]}):a.jsx(B,{size:"sm",variant:"ghost","aria-haspopup":"dialog","aria-expanded":s,title:pa,onClick:()=>r(!0),children:"Buka…"}),s&&a.jsx(se,{open:!0,title:"Buka sesi",icon:"terminal",width:420,onClose:()=>r(!1),children:a.jsx("div",{className:"hn-terminal-menu-list",children:e.map(l=>a.jsxs("button",{type:"button",disabled:l.disabled,title:l.title,className:"hn-overflow-item",onClick:()=>{r(!1),l.onSelect()},children:[l.icon&&a.jsx(Ee,{name:l.icon,size:15}),l.label]},l.key))})})]})}function Fs({sessionCount:e,focused:n,railItems:s,mobile:r,listError:l,menuFor:c,onFocus:x,drawerOpen:g,onDrawer:S,fullId:f,focusPhases:k,paneHandlers:p,fontSize:b,showKeys:y,onToggleKeys:I,predict:E,diag:z,screenReader:R}){const j=n?s.find(h=>h.session.id===n.id):void 0;return a.jsxs("div",{className:"hn-terminal-focus","data-testid":"terminal-focus",children:[!r&&e>0&&a.jsxs("aside",{className:"hn-terminal-rail","aria-label":"Sesi terminal",children:[a.jsxs("div",{className:"hn-terminal-rail-head",children:[a.jsx("span",{children:"Sesi"}),a.jsx("span",{children:e})]}),a.jsx("div",{className:"hn-terminal-rail-scroll",children:a.jsx(ua,{items:s,focusedId:(n==null?void 0:n.id)??null,onFocus:x,menuFor:c})})]}),a.jsx("section",{className:"hn-terminal-focus-main","aria-label":"Terminal fokus",children:n&&j?a.jsxs(a.Fragment,{children:[a.jsxs("header",{className:"hn-terminal-focus-head",children:[a.jsxs("span",{className:"hn-terminal-focus-title",title:j.label,children:[j.label," · ",n.id.slice(0,6)]}),a.jsx(me,{status:Aa[j.status.tone],size:"sm",variant:"dot",children:j.status.label}),a.jsx(ye,{label:`Aksi sesi ${n.id}`,items:c(n)})]}),n.exited&&a.jsx(St,{}),a.jsx(Da,{compact:r,phases:(k==null?void 0:k.sessionId)===n.id?k.phases:null}),a.jsx("div",{className:"hn-terminal-focus-body",children:f===n.id?a.jsx("div",{className:"hn-terminal-focus-placeholder",children:"Terbuka di layar penuh"}):a.jsx(jt,{sessionId:n.id,...p(n.id),fontSize:b,showKeys:y,predict:E,diag:z,screenReader:R,composer:!0,compact:r,onToggleKeys:I,label:j.label},n.id)})]}):l?null:a.jsx(Re,{kind:"empty",icon:"terminal",title:"Belum ada sesi terminal",hint:"Tekan Sesi baru untuk memulai agen di project terpilih, atau Terminal biasa untuk shell."})}),r&&g&&a.jsx(se,{open:!0,title:"Sesi terminal",icon:"terminal",width:460,onClose:()=>S(!1),children:a.jsx(ua,{items:s,focusedId:(n==null?void 0:n.id)??null,onFocus:h=>{x(h),S(!1)},menuFor:c})})]})}function St(){return a.jsxs("div",{role:"status","data-testid":"terminal-ended",className:"hn-terminal-ended",children:[a.jsx("strong",{className:"hn-terminal-ended-title",children:"Berakhir"}),a.jsx("span",{className:"hn-terminal-ended-body",children:"Agen sudah berhenti. Output tetap bisa dibaca; tutup sel bila tak diperlukan lagi."})]})}function Ps({session:e,label:n,fontSize:s,showKeys:r,predict:l,diag:c,screenReader:x,onClose:g}){return a.jsx(se,{open:!0,icon:"terminal",title:n,onClose:g,closeOnEscape:!1,width:1600,children:a.jsxs("div",{className:"hn-terminal-fullscreen-body",children:[e.exited&&a.jsx(St,{}),a.jsx(jt,{sessionId:e.id,onExit:()=>{},fontSize:s,showKeys:r,predict:l,diag:c,screenReader:x},e.id)]})})}function Ls({unplaced:e,nameOf:n,onPick:s,disabled:r}){return a.jsx("div",{className:"hn-terminal-empty-cell",children:a.jsx(Q,{size:"sm",value:"","aria-label":"Pilih sesi untuk sel",disabled:r||!e.length,onChange:l=>l.target.value&&s(l.target.value),options:[{value:"",label:e.length?"Pilih sesi…":"tidak ada sesi bebas"}].concat(e.map(l=>({value:l.id,label:`${l.specId??n(l.projectId)} · ${l.id.slice(0,6)}`})))})})}export{Da as PhaseStrip,Gs as TerminalScreen,Ma as sessionMenuItems};
|