hanoman 0.1.35 → 0.1.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.35",
3
- "sha": "ea92c04",
4
- "builtAt": "2026-08-14T15:23:07.578Z"
2
+ "version": "0.1.37",
3
+ "sha": "c2be030",
4
+ "builtAt": "2026-08-14T16:26:48.760Z"
5
5
  }
package/dist/server.js CHANGED
@@ -12177,13 +12177,14 @@ async function recordConflict(entity, recordId, local, server) {
12177
12177
  localUpdatedAt: stamp(local.data),
12178
12178
  serverData: server.data,
12179
12179
  serverVersion: server.version,
12180
- serverUpdatedAt: stamp(server.data),
12181
- resolvedAt: null
12180
+ serverUpdatedAt: stamp(server.data)
12182
12181
  };
12182
+ const prev = await prisma.syncConflict.findUnique({ where: { entity_recordId: { entity, recordId } } });
12183
+ if (prev?.resolvedAt && prev.localVersion === local.version && prev.serverVersion === server.version) return;
12183
12184
  await prisma.syncConflict.upsert({
12184
12185
  where: { entity_recordId: { entity, recordId } },
12185
- create: row,
12186
- update: { ...row, detectedAt: /* @__PURE__ */ new Date() }
12186
+ create: { ...row, resolvedAt: null },
12187
+ update: { ...row, resolvedAt: null, detectedAt: /* @__PURE__ */ new Date() }
12187
12188
  });
12188
12189
  }
12189
12190
  async function listConflicts() {
@@ -12207,8 +12208,10 @@ async function resolveConflict(entity, recordId, choice, push) {
12207
12208
  if (choice === "server") {
12208
12209
  await upsertLocal(entity, recordId, c.serverVersion, c.serverData);
12209
12210
  } else {
12210
- const res = await push([{ entity, id: recordId, baseVersion: c.serverVersion, data: c.localData }]);
12211
- const r = res.results?.[0];
12211
+ let r = (await push([{ entity, id: recordId, baseVersion: c.serverVersion, data: c.localData }])).results?.[0];
12212
+ if (!r?.ok && r?.conflict && typeof r.server?.version === "number" && r.server.version !== c.serverVersion) {
12213
+ r = (await push([{ entity, id: recordId, baseVersion: r.server.version, data: c.localData }])).results?.[0];
12214
+ }
12212
12215
  if (!r?.ok) {
12213
12216
  if (r?.conflict) return { ok: false, reason: "still-conflict" };
12214
12217
  return { ok: false, reason: "not-found" };
@@ -12332,7 +12335,12 @@ async function pinnedRequest(input) {
12332
12335
  path: `${input.url.pathname}${input.url.search}`,
12333
12336
  headers: input.headers,
12334
12337
  servername: input.url.hostname,
12335
- lookup: (_host, _opts, callback) => callback(null, input.address, input.family),
12338
+ // Node >= 20 menyalakan `autoSelectFamily` secara default: socket memanggil `lookup` dengan
12339
+ // `all: true` dan membaca `addresses[0].address` dari hasilnya. Menjawab dalam bentuk skalar
12340
+ // di situ memberi `undefined` → ERR_INVALID_IP_ADDRESS sebelum satu paket pun keluar, dan
12341
+ // pemanggil (sync tick, webhook) menelannya sebagai "offline". Kedua bentuk dijawab supaya
12342
+ // pinning tetap benar apa pun setelan family-nya.
12343
+ lookup: (_host, opts, callback) => opts.all ? callback(null, [{ address: input.address, family: input.family }]) : callback(null, input.address, input.family),
12336
12344
  timeout: input.connectMs
12337
12345
  }, (response) => {
12338
12346
  const chunks = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hanoman",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "description": "Orchestrator + dashboard workflow docs-driven untuk sesi Claude Code / Codex",
5
5
  "type": "module",
6
6
  "repository": {
@@ -7480,7 +7480,7 @@ ${t}</tr>
7480
7480
  `}strong(t){return`<strong>${t}</strong>`}em(t){return`<em>${t}</em>`}codespan(t){return`<code>${t}</code>`}br(){return"<br>"}del(t){return`<del>${t}</del>`}link(t,a,n){const i=lb(t);if(i===null)return n;t=i;let s='<a href="'+t+'"';return a&&(s+=' title="'+a+'"'),s+=">"+n+"</a>",s}image(t,a,n){const i=lb(t);if(i===null)return n;t=i;let s=`<img src="${t}" alt="${n}"`;return a&&(s+=` title="${a}"`),s+=">",s}text(t){return t}}class h2{strong(t){return t}em(t){return t}codespan(t){return t}del(t){return t}html(t){return t}text(t){return t}link(t,a,n){return""+n}image(t,a,n){return""+n}br(){return""}}class oi{constructor(t){Dt(this,"options");Dt(this,"renderer");Dt(this,"textRenderer");this.options=t||vs,this.options.renderer=this.options.renderer||new Wu,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new h2}static parse(t,a){return new oi(a).parse(t)}static parseInline(t,a){return new oi(a).parseInline(t)}parse(t,a=!0){let n="";for(let i=0;i<t.length;i++){const s=t[i];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[s.type]){const o=s,l=this.options.extensions.renderers[o.type].call({parser:this},o);if(l!==!1||!["space","hr","heading","code","table","blockquote","list","html","paragraph","text"].includes(o.type)){n+=l||"";continue}}switch(s.type){case"space":continue;case"hr":{n+=this.renderer.hr();continue}case"heading":{const o=s;n+=this.renderer.heading(this.parseInline(o.tokens),o.depth,Ire(this.parseInline(o.tokens,this.textRenderer)));continue}case"code":{const o=s;n+=this.renderer.code(o.text,o.lang,!!o.escaped);continue}case"table":{const o=s;let l="",c="";for(let h=0;h<o.header.length;h++)c+=this.renderer.tablecell(this.parseInline(o.header[h].tokens),{header:!0,align:o.align[h]});l+=this.renderer.tablerow(c);let d="";for(let h=0;h<o.rows.length;h++){const m=o.rows[h];c="";for(let p=0;p<m.length;p++)c+=this.renderer.tablecell(this.parseInline(m[p].tokens),{header:!1,align:o.align[p]});d+=this.renderer.tablerow(c)}n+=this.renderer.table(l,d);continue}case"blockquote":{const o=s,l=this.parse(o.tokens);n+=this.renderer.blockquote(l);continue}case"list":{const o=s,l=o.ordered,c=o.start,d=o.loose;let h="";for(let m=0;m<o.items.length;m++){const p=o.items[m],g=p.checked,_=p.task;let S="";if(p.task){const y=this.renderer.checkbox(!!g);d?p.tokens.length>0&&p.tokens[0].type==="paragraph"?(p.tokens[0].text=y+" "+p.tokens[0].text,p.tokens[0].tokens&&p.tokens[0].tokens.length>0&&p.tokens[0].tokens[0].type==="text"&&(p.tokens[0].tokens[0].text=y+" "+p.tokens[0].tokens[0].text)):p.tokens.unshift({type:"text",text:y+" "}):S+=y+" "}S+=this.parse(p.tokens,d),h+=this.renderer.listitem(S,_,!!g)}n+=this.renderer.list(h,l,c);continue}case"html":{const o=s;n+=this.renderer.html(o.text,o.block);continue}case"paragraph":{const o=s;n+=this.renderer.paragraph(this.parseInline(o.tokens));continue}case"text":{let o=s,l=o.tokens?this.parseInline(o.tokens):o.text;for(;i+1<t.length&&t[i+1].type==="text";)o=t[++i],l+=`
7481
7481
  `+(o.tokens?this.parseInline(o.tokens):o.text);n+=a?this.renderer.paragraph(l):l;continue}default:{const o='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}parseInline(t,a){a=a||this.renderer;let n="";for(let i=0;i<t.length;i++){const s=t[i];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[s.type]){const o=this.options.extensions.renderers[s.type].call({parser:this},s);if(o!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(s.type)){n+=o||"";continue}}switch(s.type){case"escape":{const o=s;n+=a.text(o.text);break}case"html":{const o=s;n+=a.html(o.text);break}case"link":{const o=s;n+=a.link(o.href,o.title,this.parseInline(o.tokens,a));break}case"image":{const o=s;n+=a.image(o.href,o.title,o.text);break}case"strong":{const o=s;n+=a.strong(this.parseInline(o.tokens,a));break}case"em":{const o=s;n+=a.em(this.parseInline(o.tokens,a));break}case"codespan":{const o=s;n+=a.codespan(o.text);break}case"br":{n+=a.br();break}case"del":{const o=s;n+=a.del(this.parseInline(o.tokens,a));break}case"text":{const o=s;n+=a.text(o.text);break}default:{const o='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}}class ql{constructor(t){Dt(this,"options");this.options=t||vs}preprocess(t){return t}postprocess(t){return t}processAllTokens(t){return t}}Dt(ql,"passThroughHooks",new Set(["preprocess","postprocess","processAllTokens"]));var _s,$f,sA;class cse{constructor(...t){W2(this,_s);Dt(this,"defaults",s2());Dt(this,"options",this.setOptions);Dt(this,"parse",Vc(this,_s,$f).call(this,si.lex,oi.parse));Dt(this,"parseInline",Vc(this,_s,$f).call(this,si.lexInline,oi.parseInline));Dt(this,"Parser",oi);Dt(this,"Renderer",Wu);Dt(this,"TextRenderer",h2);Dt(this,"Lexer",si);Dt(this,"Tokenizer",Vu);Dt(this,"Hooks",ql);this.use(...t)}walkTokens(t,a){var i,s;let n=[];for(const o of t)switch(n=n.concat(a.call(this,o)),o.type){case"table":{const l=o;for(const c of l.header)n=n.concat(this.walkTokens(c.tokens,a));for(const c of l.rows)for(const d of c)n=n.concat(this.walkTokens(d.tokens,a));break}case"list":{const l=o;n=n.concat(this.walkTokens(l.items,a));break}default:{const l=o;(s=(i=this.defaults.extensions)==null?void 0:i.childTokens)!=null&&s[l.type]?this.defaults.extensions.childTokens[l.type].forEach(c=>{const d=l[c].flat(1/0);n=n.concat(this.walkTokens(d,a))}):l.tokens&&(n=n.concat(this.walkTokens(l.tokens,a)))}}return n}use(...t){const a=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(n=>{const i={...n};if(i.async=this.defaults.async||i.async||!1,n.extensions&&(n.extensions.forEach(s=>{if(!s.name)throw new Error("extension name required");if("renderer"in s){const o=a.renderers[s.name];o?a.renderers[s.name]=function(...l){let c=s.renderer.apply(this,l);return c===!1&&(c=o.apply(this,l)),c}:a.renderers[s.name]=s.renderer}if("tokenizer"in s){if(!s.level||s.level!=="block"&&s.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");const o=a[s.level];o?o.unshift(s.tokenizer):a[s.level]=[s.tokenizer],s.start&&(s.level==="block"?a.startBlock?a.startBlock.push(s.start):a.startBlock=[s.start]:s.level==="inline"&&(a.startInline?a.startInline.push(s.start):a.startInline=[s.start]))}"childTokens"in s&&s.childTokens&&(a.childTokens[s.name]=s.childTokens)}),i.extensions=a),n.renderer){const s=this.defaults.renderer||new Wu(this.defaults);for(const o in n.renderer){if(!(o in s))throw new Error(`renderer '${o}' does not exist`);if(o==="options")continue;const l=o,c=n.renderer[l],d=s[l];s[l]=(...h)=>{let m=c.apply(s,h);return m===!1&&(m=d.apply(s,h)),m||""}}i.renderer=s}if(n.tokenizer){const s=this.defaults.tokenizer||new Vu(this.defaults);for(const o in n.tokenizer){if(!(o in s))throw new Error(`tokenizer '${o}' does not exist`);if(["options","rules","lexer"].includes(o))continue;const l=o,c=n.tokenizer[l],d=s[l];s[l]=(...h)=>{let m=c.apply(s,h);return m===!1&&(m=d.apply(s,h)),m}}i.tokenizer=s}if(n.hooks){const s=this.defaults.hooks||new ql;for(const o in n.hooks){if(!(o in s))throw new Error(`hook '${o}' does not exist`);if(o==="options")continue;const l=o,c=n.hooks[l],d=s[l];ql.passThroughHooks.has(o)?s[l]=h=>{if(this.defaults.async)return Promise.resolve(c.call(s,h)).then(p=>d.call(s,p));const m=c.call(s,h);return d.call(s,m)}:s[l]=(...h)=>{let m=c.apply(s,h);return m===!1&&(m=d.apply(s,h)),m}}i.hooks=s}if(n.walkTokens){const s=this.defaults.walkTokens,o=n.walkTokens;i.walkTokens=function(l){let c=[];return c.push(o.call(this,l)),s&&(c=c.concat(s.call(this,l))),c}}this.defaults={...this.defaults,...i}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,a){return si.lex(t,a??this.defaults)}parser(t,a){return oi.parse(t,a??this.defaults)}}_s=new WeakSet,$f=function(t,a){return(n,i)=>{const s={...i},o={...this.defaults,...s};this.defaults.async===!0&&s.async===!1&&(o.silent||console.warn("marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored."),o.async=!0);const l=Vc(this,_s,sA).call(this,!!o.silent,!!o.async);if(typeof n>"u"||n===null)return l(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(o.hooks&&(o.hooks.options=o),o.async)return Promise.resolve(o.hooks?o.hooks.preprocess(n):n).then(c=>t(c,o)).then(c=>o.hooks?o.hooks.processAllTokens(c):c).then(c=>o.walkTokens?Promise.all(this.walkTokens(c,o.walkTokens)).then(()=>c):c).then(c=>a(c,o)).then(c=>o.hooks?o.hooks.postprocess(c):c).catch(l);try{o.hooks&&(n=o.hooks.preprocess(n));let c=t(n,o);o.hooks&&(c=o.hooks.processAllTokens(c)),o.walkTokens&&this.walkTokens(c,o.walkTokens);let d=a(c,o);return o.hooks&&(d=o.hooks.postprocess(d)),d}catch(c){return l(c)}}},sA=function(t,a){return n=>{if(n.message+=`
7482
7482
  Please report this to https://github.com/markedjs/marked.`,t){const i="<p>An error occurred:</p><pre>"+_n(n.message+"",!0)+"</pre>";return a?Promise.resolve(i):i}if(a)return Promise.reject(n);throw n}};const hs=new cse;function Ct(e,t){return hs.parse(e,t)}Ct.options=Ct.setOptions=function(e){return hs.setOptions(e),Ct.defaults=hs.defaults,QM(Ct.defaults),Ct};Ct.getDefaults=s2;Ct.defaults=vs;Ct.use=function(...e){return hs.use(...e),Ct.defaults=hs.defaults,QM(Ct.defaults),Ct};Ct.walkTokens=function(e,t){return hs.walkTokens(e,t)};Ct.parseInline=hs.parseInline;Ct.Parser=oi;Ct.parser=oi.parse;Ct.Renderer=Wu;Ct.TextRenderer=h2;Ct.Lexer=si;Ct.lexer=si.lex;Ct.Tokenizer=Vu;Ct.Hooks=ql;Ct.parse=Ct;Ct.options;Ct.setOptions;Ct.use;Ct.walkTokens;Ct.parseInline;oi.parse;si.lex;const dse=["a","blockquote","br","code","del","em","h1","h2","h3","h4","h5","h6","hr","img","input","li","ol","p","pre","strong","table","tbody","td","th","thead","tr","ul"],use=["align","alt","checked","class","disabled","href","src","start","title","type"],hse=["href","src"],pse=new Set(["http","https","mailto"]),mse=new Set(["http","https"]);function _se(e){return e.replace(/[&<>]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;"})[t])}function gse(e,t){var i,s;const a=e.replace(/[\u0000-\u0020\u007f-\u009f]/g,""),n=(s=(i=/^([a-z][a-z\d+.-]*):/i.exec(a))==null?void 0:i[1])==null?void 0:s.toLowerCase();return n?(t==="href"?pse:mse).has(n):!0}function fse(e){const t=e.tagName.toLowerCase(),a=t==="ul"?new Set(["contains-task-list"]):t==="li"?new Set(["task-list-item"]):null;return e.className.split(/\s+/).filter(n=>(a==null?void 0:a.has(n))||t==="code"&&/^language-[\w-]+$/.test(n))}function yse(e){var n;const t=Rre.sanitize(e,{ALLOWED_TAGS:dse,ALLOWED_ATTR:use,ALLOW_ARIA_ATTR:!1,ALLOW_DATA_ATTR:!1}),a=document.createElement("template");a.innerHTML=t;for(const i of a.content.querySelectorAll("[href], [src]"))for(const s of hse){const o=i.getAttribute(s);o!==null&&!gse(o,s)&&i.removeAttribute(s)}for(const i of a.content.querySelectorAll("[class]")){const s=fse(i);s.length?i.setAttribute("class",s.join(" ")):i.removeAttribute("class")}for(const i of a.content.querySelectorAll("input"))((n=i.getAttribute("type"))==null?void 0:n.toLowerCase())!=="checkbox"?i.remove():i.setAttribute("disabled","");return a.innerHTML}function Sse(e){try{const t=Ct.parse(e||"",{gfm:!0,breaks:!1});return yse(t)}catch{return"<pre>"+_se(String(e||""))+"</pre>"}}function vse(e){return/\.json$/.test(e)?"json":/\.toml$/.test(e)?"toml":/\.ya?ml$/.test(e)?"yaml":/\.(ts|tsx|js)$/.test(e)?"ts":""}const go=e=>/\.md$/i.test(e);function bse(e,t){const a=/\.md$/.test(t)?e||"":"```"+vse(t)+`
7483
- `+(e||"")+"\n```";return Sse(a)}function Ar({text:e,name:t}){return r.jsx("div",{className:"hn-md",dangerouslySetInnerHTML:{__html:bse(e,t)}})}function Do({href:e,disabled:t=!1,size:a="sm"}){return t?null:r.jsxs("div",{style:{display:"flex",gap:4},children:[r.jsx(B,{as:"a",href:e("md"),download:!0,size:a,variant:"ghost",leftIcon:"download",title:"Unduh sumber Markdown","aria-label":"Unduh .md",children:".md"}),r.jsx(B,{as:"a",href:e("pdf"),download:!0,size:a,variant:"ghost",leftIcon:"file-down",title:"Unduh sebagai PDF","aria-label":"Unduh .pdf",children:".pdf"})]})}function p2({path:e,text:t,eyebrow:a,download:n,onClose:i}){const s=e.slice(e.lastIndexOf("/")+1)||e;return r.jsx(Tt,{open:!0,title:s,eyebrow:a??e,icon:"book-open",onClose:i,width:980,fillHeight:!0,children:r.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},children:[n&&r.jsx("div",{style:{display:"flex",justifyContent:"flex-end",paddingBottom:6,borderBottom:"1px solid var(--border-hair)",marginBottom:8},children:r.jsx(Do,{href:n})}),r.jsx("div",{"data-testid":"doc-preview-scroll",style:{flex:"1 1 0",minHeight:0,overflow:"auto",padding:"0 4px 8px"},children:t?r.jsx(Ar,{text:t,name:e}):r.jsx(ue,{kind:"empty",icon:"file-text",title:"Berkas kosong",hint:e})})]})})}function Mh({screen:e,active:t,onReset:a,label:n="Reset tampilan"}){return r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[t>0&&r.jsxs(Ne,{tone:"warn",size:"sm",icon:"filter",children:[t," filter aktif"]}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"rotate-ccw",disabled:t===0,onClick:()=>{qie(e),a==null||a()},children:n})]})}function Ku(e){return e==="codex"?mo:F0}function m2(e,t){return e==="codex"?qs(t):rM}function Vf(e,t){const a=e[t];return{model:a.model,effort:t==="codex"?wn(a.model,a.effort):a.effort}}function Ese({needsSetup:e,onDone:t}){const[a,n]=f.useState(""),[i,s]=f.useState(""),[o,l]=f.useState(""),[c,d]=f.useState(!1),[h,m]=f.useState(""),p=/\S+@\S+\.\S+/.test(a)&&i.length>=(e?8:1)&&(!e||o.trim().length>0);async function g(){if(!(!p||c)){d(!0),m("");try{const{user:_}=await(e?F.setup({email:a,password:i,setupToken:o.trim()}):F.login({email:a,password:i}));t(_)}catch(_){m(e?_ instanceof Mt&&_.status===409?"Sudah ada akun — silakan masuk.":"Gagal membuat akun. Password minimal 8 karakter.":"Email atau password salah."),d(!1)}}}return r.jsx("div",{"data-testid":"auth-scroll",className:"hn-dynamic-viewport",style:{minHeight:"100dvh",height:"100dvh",display:"flex",overflowY:"auto",background:"var(--bone-100)",boxSizing:"border-box",padding:"max(24px, var(--safe-top)) max(16px, var(--safe-right)) max(24px, var(--safe-bottom)) max(16px, var(--safe-left))"},children:r.jsxs("div",{style:{width:"100%",maxWidth:380,margin:"auto"},children:[r.jsx("div",{style:{display:"flex",justifyContent:"center",marginBottom:20},children:r.jsx(cie,{})}),r.jsxs(be,{eyebrow:e?"hanoman · setup":"hanoman · masuk",title:e?"Buat akun pertama":"Masuk",children:[r.jsx(PM,{id:"PST-001",priority:!0,style:{width:"100%",maxHeight:184,marginBottom:14,borderRadius:"var(--radius-md)"}}),r.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:16,lineHeight:1.5},children:e?"Belum ada akun. Akun pertama ini yang bisa mengundang user lain.":"Masuk dengan email dan password."}),r.jsxs("form",{onSubmit:_=>{_.preventDefault(),g()},children:[r.jsx(fe,{label:"Email",children:r.jsx(je,{type:"email",autoComplete:"username",value:a,placeholder:"kamu@nafanesia.id",onChange:_=>n(_.target.value),style:{width:"100%"}})}),r.jsx(fe,{label:"Password",hint:e?"minimal 8 karakter":void 0,children:r.jsx(je,{type:"password",autoComplete:e?"new-password":"current-password",value:i,placeholder:"••••••••",onChange:_=>s(_.target.value),style:{width:"100%"}})}),e&&r.jsx(fe,{label:"Setup token",hint:"baca setup.token di HANOMAN_HOME pada host server",children:r.jsx(je,{type:"password",autoComplete:"off",value:o,onChange:_=>l(_.target.value),style:{width:"100%"}})}),h&&r.jsx("div",{style:{fontSize:12.5,color:"var(--status-err)",marginBottom:12},children:h}),r.jsx(B,{type:"submit",leftIcon:e?"user-plus":"log-in",disabled:!p||c,style:{width:"100%",justifyContent:"center"},children:c?"Memproses…":e?"Buat akun & masuk":"Masuk"})]})]})]})})}async function rl(e){const t=await fetch(e,{headers:{"content-type":"application/json"}});if(!t.ok)throw new Mt(t.status,`GET ${e} → ${t.status}`);return t.json()}const sl=e=>`/api/portal/projects/${encodeURIComponent(e)}`,hb=({page:e,limit:t})=>`?page=${e}&limit=${t}`,Gr={listProjects:()=>rl("/api/portal/projects"),listBacklog:(e,t)=>rl(`${sl(e)}/backlog${hb(t)}`),getSpec:(e,t)=>rl(`${sl(e)}/backlog/${encodeURIComponent(t)}`),listTickets:(e,t)=>rl(`${sl(e)}/tickets${hb(t)}`),getTicket:(e,t)=>rl(`${sl(e)}/tickets/${encodeURIComponent(t)}`),createTicket:async(e,t)=>{const a=`${sl(e)}/tickets`,n=await fetch(a,{method:"POST",body:t});if(!n.ok)throw new Mt(n.status,`POST ${a} → ${n.status}`);return n.json()},logout:async()=>{const e=await fetch("/api/auth/logout",{method:"POST"});if(!e.ok)throw new Mt(e.status,`POST /api/auth/logout → ${e.status}`)}},kse={"Sedang ditinjau":"queued",Diterima:"awaiting","Sedang dikerjakan":"running",Selesai:"done",Ditutup:"failed"},xse={brainstorming:"queued",objective:"queued","spec-ready":"queued",planned:"queued",executing:"running",done:"done"},pb=e=>kse[e]??"idle",mb=e=>xse[e]??"idle",Tse={bug:"Bug",fitur:"Permintaan fitur",pertanyaan:"Pertanyaan",lainnya:"Lainnya"},wp=3;function Cse({projects:e,activeId:t,onCancel:a,onSent:n}){const[i,s]=f.useState(t),[o,l]=f.useState(Of.options[0]),[c,d]=f.useState(""),[h,m]=f.useState(""),[p,g]=f.useState([]),[_,S]=f.useState(!1),[y,v]=f.useState(null),b=async()=>{v(null),S(!0);try{const E=new FormData;E.set("category",o),E.set("title",c),E.set("detail",h);for(const k of p.slice(0,wp))E.append("files",k,k.name);await Gr.createTicket(i,E),n(i)}catch{v("Gagal mengirim keluhan. Coba lagi sebentar.")}finally{S(!1)}};return r.jsxs(Tt,{open:!0,title:"Kirim keluhan",icon:"send",eyebrow:"help desk",onClose:a,children:[r.jsx(fe,{label:"Project",children:r.jsx(xe,{"aria-label":"Project",value:i,onChange:E=>s(E.target.value),options:e.map(E=>({value:E.id,label:E.name})),style:{width:"100%"}})}),r.jsx(fe,{label:"Kategori",children:r.jsx(xe,{"aria-label":"Kategori",value:o,onChange:E=>l(E.target.value),options:Of.options.map(E=>({value:E,label:Tse[E]??E})),style:{width:"100%"}})}),r.jsx(fe,{label:"Judul",children:r.jsx("input",{"aria-label":"Judul",value:c,onChange:E=>d(E.target.value),maxLength:200,placeholder:"mis. Tombol Simpan tak berfungsi di HP",style:wse})}),r.jsx(fe,{label:"Detail",children:r.jsx(Ta,{"aria-label":"Detail",value:h,onChange:E=>m(E.target.value),rows:5,placeholder:"mis. Buka halaman Pesanan di HP, tekan Simpan — layar diam dan datanya tak tersimpan."})}),r.jsx(fe,{label:"Lampiran gambar",hint:`Opsional, maksimal ${wp} berkas PNG/JPEG/WebP.`,children:r.jsx("input",{"aria-label":"Lampiran gambar",type:"file",accept:"image/png,image/jpeg,image/webp",multiple:!0,onChange:E=>g(Array.from(E.target.files??[]).slice(0,wp))})}),y&&r.jsx("div",{style:{color:"var(--clay-600)",fontSize:13,marginBottom:8},children:y}),r.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",marginTop:8},children:[r.jsx(B,{size:"sm",variant:"secondary",onClick:a,children:"Batal"}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"send",disabled:_||!c.trim()||!h.trim(),onClick:b,children:"Kirim"})]})]})}const wse={display:"block",width:"100%",boxSizing:"border-box",padding:"9px 11px",border:"1px solid var(--border-strong)",borderRadius:"var(--radius-sm)",background:"var(--surface-card)",color:"var(--text-strong)",fontSize:13,fontFamily:"var(--font-ui)"},Ls=e=>e?new Date(e).toLocaleDateString("id-ID",{day:"numeric",month:"short",year:"numeric"}):"—",_b={brainstorming:"Dirumuskan",objective:"Dirumuskan","spec-ready":"Disiapkan",planned:"Direncanakan",executing:"Sedang dikerjakan",done:"Selesai"},Qu=20,Ed={items:[],total:0,page:1,pageSize:Qu};function gb({total:e,page:t,onPage:a,unit:n}){const i=gi(e,t,Qu);return r.jsx("div",{style:{marginTop:14,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflow:"hidden"},children:r.jsx(fi,{page:i.page,pageCount:i.pageCount,total:e,from:i.from,to:i.to,onPage:a,unit:n})})}function Rse({user:e,onLoggedOut:t}){const[a,n]=f.useState(null),[i,s]=f.useState(null),[o,l]=f.useState("backlog"),[c,d]=f.useState(Ed),[h,m]=f.useState(Ed),[p,g]=f.useState(1),[_,S]=f.useState(1),[y,v]=f.useState(0),[b,E]=f.useState(null),[k,T]=f.useState(null),[A,M]=f.useState(!1),[x,P]=f.useState(!1);f.useEffect(()=>{Gr.listProjects().then(w=>{n(w.items),s(O=>{var H;return O??((H=w.items[0])==null?void 0:H.id)??null})}).catch(()=>{n([]),M(!0)})},[]);const R=f.useRef(0),G=f.useCallback((w,O,H)=>{const N=++R.current;Promise.all([Gr.listBacklog(w,{page:O,limit:Qu}),Gr.listTickets(w,{page:H,limit:Qu})]).then(([z,U])=>{N===R.current&&(d(z),m(U))}).catch(()=>{N===R.current&&(d(Ed),m(Ed))})},[]);f.useEffect(()=>{i&&G(i,p,_)},[i,p,_,y,G]),f.useEffect(()=>{g(1),S(1)},[i,o]);const j=async()=>{try{await Gr.logout()}catch{}finally{t()}};return r.jsxs("div",{"data-testid":"portal-root",className:"hn-dynamic-viewport",style:{height:"100dvh",minHeight:0,display:"flex",flexDirection:"column",background:"var(--surface-page)",color:"var(--text-body)"},children:[r.jsxs("header",{className:"hn-portal-header",style:{...Mr,display:"flex",alignItems:"center",gap:14,padding:"0 22px",height:"var(--topbar-h)",borderBottom:"1px solid var(--border-hair)",background:"var(--bone-100)"},children:[r.jsx("span",{style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:26,height:26,borderRadius:"var(--radius-sm)",background:"var(--accent)"},children:r.jsx(e2,{id:"buntut",size:17,color:"#fff"})}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:18,fontWeight:600,color:"var(--text-strong)"},children:"Portal klien"}),r.jsx("div",{style:{flex:1}}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-subtle)"},children:e.email}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"log-out",onClick:j,children:"Keluar"})]}),r.jsx("main",{"data-testid":"portal-scroll",style:gc,children:r.jsx("div",{className:"hn-portal-content",style:{maxWidth:"var(--content-max)",margin:"0 auto",padding:"24px 28px 32px"},children:a===null?r.jsx(ue,{kind:"loading",title:"Memuat…"}):a.length===0?r.jsx(ue,{kind:A?"error":"empty",icon:"folder",title:A?"Gagal memuat data":"Belum ada project yang bisa dilihat",hint:A?"Coba muat ulang halaman ini.":"Hubungi tim hanoman untuk meminta akses ke project Anda."}):r.jsxs(r.Fragment,{children:[r.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8,marginBottom:18},children:a.map(w=>r.jsx(B,{size:"sm",variant:w.id===i?"primary":"ghost",onClick:()=>s(w.id),children:w.name},w.id))}),r.jsxs("div",{className:"hn-portal-toolbar",style:{display:"flex",alignItems:"center",gap:12,marginBottom:14},children:[r.jsx(mi,{value:o,onChange:l,style:{flex:1,minWidth:0},tabs:[{value:"backlog",label:"Pekerjaan",count:c.total},{value:"tickets",label:"Help desk",count:h.total}]}),r.jsx(B,{size:"sm",leftIcon:"send",onClick:()=>P(!0),children:"Kirim keluhan"})]}),o==="backlog"?c.total===0?r.jsx(ue,{kind:"empty",icon:"list-checks",title:"Belum ada pekerjaan tercatat",hint:"Begitu tim mulai mengerjakan sesuatu di project ini, daftarnya muncul di sini."}):r.jsxs(r.Fragment,{children:[r.jsx(be,{padding:0,"data-testid":"portal-list",children:c.items.map(w=>r.jsxs("button",{type:"button",className:"hn-portal-row",onClick:()=>void Gr.getSpec(i,w.id).then(E),style:fb,children:[r.jsx("span",{style:{...Hn,fontFamily:"var(--font-mono)",width:92},children:w.id}),r.jsx("span",{style:{flex:1,minWidth:0,fontWeight:500,color:"var(--text-strong)"},children:w.title}),r.jsx(Oa,{status:mb(w.stage),size:"sm",children:_b[w.stage]??w.stage}),r.jsx("span",{style:Hn,children:w.priority}),r.jsx("span",{style:Hn,children:Ls(w.doneAt??w.startedAt??w.createdAt)})]},w.id))}),r.jsx(gb,{total:c.total,page:p,onPage:g,unit:"pekerjaan"})]}):h.total===0?r.jsx(ue,{kind:"empty",icon:"inbox",title:"Belum ada tiket",hint:"Kirim keluhan lewat tombol Kirim keluhan di atas — atau lewat halaman Help Center project ini."}):r.jsxs(r.Fragment,{children:[r.jsx(be,{padding:0,"data-testid":"portal-list",children:h.items.map(w=>r.jsxs("button",{type:"button",className:"hn-portal-row",onClick:()=>void Gr.getTicket(i,w.id).then(T),style:fb,children:[r.jsxs("span",{style:{...Hn,fontFamily:"var(--font-mono)",width:48},children:["#",w.number]}),r.jsx("span",{style:{flex:1,minWidth:0,fontWeight:500,color:"var(--text-strong)"},children:w.title}),r.jsx("span",{style:Hn,children:w.category}),r.jsx(Oa,{status:pb(w.status),size:"sm",children:w.status}),r.jsx("span",{style:Hn,children:Ls(w.createdAt)})]},w.id))}),r.jsx(gb,{total:h.total,page:_,onPage:S,unit:"tiket"})]})]})})}),x&&a&&a.length>0&&r.jsx(Cse,{projects:a,activeId:i,onCancel:()=>P(!1),onSent:w=>{P(!1),l("tickets"),S(1),w===i?v(O=>O+1):s(w)}}),r.jsx(Tt,{open:!!b,title:(b==null?void 0:b.title)??"",eyebrow:b==null?void 0:b.id,onClose:()=>E(null),children:b&&r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[r.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[r.jsx(Oa,{status:mb(b.stage),size:"sm",children:_b[b.stage]??b.stage}),r.jsxs("span",{style:Hn,children:["prioritas ",b.priority]})]}),r.jsx("p",{style:{margin:0,lineHeight:1.6},children:b.objective}),r.jsxs("dl",{style:Mse,children:[r.jsx("dt",{style:Hn,children:"Dibuat"}),r.jsx("dd",{style:Rp,children:Ls(b.createdAt)}),r.jsx("dt",{style:Hn,children:"Mulai"}),r.jsx("dd",{style:Rp,children:Ls(b.startedAt)}),r.jsx("dt",{style:Hn,children:"Selesai"}),r.jsx("dd",{style:Rp,children:Ls(b.doneAt)})]})]})}),r.jsx(Tt,{open:!!k,title:(k==null?void 0:k.title)??"",eyebrow:k?`#${k.number} · ${k.category}`:void 0,onClose:()=>T(null),children:k&&r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[r.jsx("div",{children:r.jsx(Oa,{status:pb(k.status),size:"sm",children:k.status})}),r.jsx("p",{style:{margin:0,whiteSpace:"pre-wrap",lineHeight:1.6},children:k.detail}),r.jsxs("span",{style:Hn,children:["Dikirim ",Ls(k.createdAt)]})]})})]})}const fb={display:"flex",alignItems:"center",gap:12,width:"100%",padding:"12px 16px",border:"none",borderBottom:"1px solid var(--border-hair)",cursor:"pointer",background:"transparent",color:"inherit",font:"inherit",textAlign:"left"},Hn={fontSize:"var(--text-sm)",color:"var(--text-subtle)"},Mse={display:"grid",gridTemplateColumns:"auto 1fr",gap:"6px 16px",margin:0},Rp={margin:0,fontSize:"var(--text-sm)"};function oA(e,t){return[{value:"",label:e.length?"main (default project)":"project belum punya repo"}].concat(e.map(a=>({value:a,label:t!=null&&t.has(a)?`${a} · origin`:a})))}const Ase=e=>`prd/${e.replace(/^docs\/prd\//,"").replace(/\.md$/,"")}`;function Ose(e){const t=/(?:^|[#&])spec=([^&]+)/.exec(e||"");return t&&t[1]?decodeURIComponent(t[1]):null}function Yf(e,t=window.location){return`${t.origin}${t.pathname}#spec=${encodeURIComponent(e)}`}function Nse(e){const t=/(?:^|[#&])changelog=([^&]+)/.exec(e||"");if(!t||!t[1])return null;const a=/(?:^|[#&])cl=([^&]+)/.exec(e);return{projectId:decodeURIComponent(t[1]),changelogId:a&&a[1]?decodeURIComponent(a[1]):null}}function lA(e,t,a=window.location){const n=t?`&cl=${encodeURIComponent(t)}`:"";return`${a.origin}${a.pathname}#changelog=${encodeURIComponent(e)}${n}`}function Ise(e){return e==="broken"?"err":e==="drift"?"warn":"ok"}function Tl(e){return e.docStatus==="broken"?"high":e.docStatus==="drift"?"low":"none"}const Dse={high:{bar:"var(--clay-500)",tint:"var(--clay-100)",text:"var(--clay-600)",label:"perlu perhatian"},low:{bar:"var(--amber-500)",tint:"var(--amber-100)",text:"var(--amber-600)",label:"docs drift"}};function Lse({items:e}){return r.jsx("div",{className:"hn-stat-grid",style:{display:"grid",gridTemplateColumns:`repeat(${e.length}, 1fr)`,gap:1,background:"var(--border-hair)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflow:"hidden",marginBottom:20},children:e.map(t=>r.jsxs("div",{style:{background:"var(--surface-card)",padding:"16px 18px"},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:7},children:[r.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:t.dot}}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:27,fontWeight:600,color:"var(--text-strong)",lineHeight:1},children:t.value})]}),r.jsx("div",{style:{fontSize:12,color:"var(--text-muted)",marginTop:6},children:t.label}),t.sub&&r.jsx("div",{style:{fontFamily:"var(--font-mono)",fontSize:10.5,color:"var(--text-subtle)",marginTop:3},children:t.sub})]},t.label))})}function Pse({p:e,onOpen:t}){const a=Tl(e),n=Dse[a],i=e.docStatus==="broken"?"Docs off-convention":"Docs drift — sebagian kategori belum ter-index";return r.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:12,padding:"12px 4px",borderBottom:"1px solid var(--border-hair)",borderLeft:`3px solid ${n.bar}`,paddingLeft:12},children:[r.jsxs("div",{style:{minWidth:0,flex:1},children:[r.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",alignItems:"center",gap:8},children:[r.jsx(Ie,{name:"box",size:13,color:"var(--text-muted)"}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:13.5,fontWeight:500,color:"var(--text-strong)"},children:e.name}),r.jsx(Ne,{tone:a==="high"?"err":"warn",size:"sm",children:n.label})]}),r.jsxs("div",{style:{fontSize:12,color:"var(--text-muted)",marginTop:4},children:[i," · ",e.coverage,"% ter-index"]})]}),r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"book-open",onClick:()=>t(e),children:"Buka SoT"})]})}function Bse({p:e,onGoto:t}){return r.jsxs("div",{className:"hn-dense-row",role:"button",tabIndex:0,onClick:()=>t("terminal"),onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),t("terminal"))},style:{display:"flex",alignItems:"center",gap:8,padding:"12px 4px",borderBottom:"1px solid var(--border-hair)",cursor:"pointer"},children:[r.jsx(Oa,{status:"running",size:"sm",children:e.session.phase??"—"}),r.jsx("span",{style:{fontSize:13.5,fontWeight:500,color:"var(--text-strong)",flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.name}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)"},children:e.session.flow??""})]})}function jse({p:e,onOpen:t}){return r.jsxs("div",{className:"hn-grid-mobile",role:"button",tabIndex:0,onClick:()=>t(e),onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),t(e))},style:{display:"grid",gridTemplateColumns:"92px minmax(0, 1fr) 120px",alignItems:"center",gap:12,padding:"9px 4px",cursor:"pointer",borderBottom:"1px solid var(--border-hair)"},children:[r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12.5,color:"var(--text-strong)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.name}),r.jsx(Oc,{value:e.coverage,tone:Ise(e.docStatus),size:"sm"}),r.jsx(Oa,{status:e.docStatus,size:"sm",style:{justifySelf:"end"}})]})}function kd({icon:e,label:t,value:a,tone:n}){return r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"10px 12px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",background:"var(--bone-100)"},children:[r.jsx("span",{style:{width:30,height:30,borderRadius:"var(--radius-sm)",flex:"0 0 auto",background:"var(--surface-card)",border:"1px solid var(--border-hair)",color:n||"var(--text-muted)",display:"inline-flex",alignItems:"center",justifyContent:"center"},children:r.jsx(Ie,{name:e,size:15})}),r.jsxs("div",{style:{minWidth:0},children:[r.jsx("div",{style:{fontFamily:"var(--font-display)",fontSize:20,fontWeight:600,color:"var(--text-strong)",lineHeight:1},children:a}),r.jsx("div",{style:{fontSize:11.5,color:"var(--text-muted)",marginTop:3},children:t})]})]})}function Fse({projects:e,backlog:t,onOpenProject:a,onGoto:n}){const i=jM(),s=FM(),o=e.filter(b=>b.session.status==="running"),l=e.filter(b=>Tl(b)!=="none").sort((b,E)=>(Tl(b)==="high"?0:1)-(Tl(E)==="high"?0:1)),c=e.filter(b=>b.docStatus==="ok").length,d=e.filter(b=>Tl(b)==="high").length,h=e.length?Math.round(e.reduce((b,E)=>b+E.coverage,0)/e.length):0,m=t.filter(b=>b.source==="brief").length,p=t.filter(b=>b.source==="qa").length,g=t.filter(b=>b.source==="audit").length,_=t.filter(b=>b.priority==="tinggi").length,S=[...e].sort((b,E)=>b.coverage-E.coverage),y=e.map(b=>({project:b.name,status:b.session.status,text:b.activity,commit:b.commit})),v=[{label:"Sesi aktif",value:o.length,dot:"var(--brass-500)"},{label:"Perlu perhatian",value:d,dot:"var(--clay-600)"},{label:"Docs on-convention",value:c+"/"+e.length,sub:"rata-rata "+h+"%",dot:"var(--leaf-600)"},{label:"Spec di backlog",value:t.length,sub:m+" brief · "+p+" QA · "+g+" audit",dot:"var(--wind-600)"}];return r.jsxs("div",{children:[r.jsx(Lse,{items:v}),r.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"1.35fr 1fr",gap:20,alignItems:"start"},children:[r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:20},children:[r.jsx(be,{eyebrow:"needs attention · "+l.length,title:"Perlu perhatian",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"layout-grid",onClick:()=>n("projects"),children:"Semua project"}),children:l.length===0?r.jsx(ue,{kind:"empty",compact:!0,illustration:"PST-005",illustrationDecorative:!0,title:"Semua project on-convention",hint:"Source of Truth utuh — tidak ada yang perlu perhatian."}):r.jsx("div",{style:{marginTop:4},children:l.map(b=>r.jsx(Pse,{p:b,onOpen:a},b.id))})}),r.jsx(be,{eyebrow:"live · "+o.length+" berjalan",title:"Claude Code sedang jalan",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"terminal",onClick:()=>n("terminal"),children:"Buka Terminal"}),children:o.length===0?r.jsx(ue,{kind:"empty",compact:!0,icon:"terminal",title:"Tidak ada sesi aktif",hint:"Mulai sebuah backlog item untuk membuka sesi Claude Code interaktif."}):r.jsx("div",{style:{marginTop:4},children:o.map(b=>r.jsx(Bse,{p:b,onGoto:n},b.id))})})]}),r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:20},children:[r.jsx(be,{eyebrow:"realtime · Claude",title:"Limit langganan",children:r.jsx(qu,{dto:i})}),s.status!=="unavailable"&&r.jsx(be,{eyebrow:`snapshot · Codex${s.plan?` · ${s.plan}`:""}`,title:"Limit langganan",children:r.jsx(qu,{dto:s})}),r.jsx(be,{eyebrow:"Source of Truth",title:"Docs coverage",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"book-open",onClick:()=>n("docs"),children:"Docs"}),children:S.length===0?r.jsx(ue,{kind:"empty",compact:!0,icon:"book-open",title:"Belum ada project",hint:"Coverage Source of Truth muncul setelah project pertama ditambahkan."}):r.jsx("div",{style:{marginTop:4},children:S.map(b=>r.jsx(jse,{p:b,onOpen:a},b.id))})}),r.jsx(be,{eyebrow:"brainstorm → execute",title:"Backlog",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"list-checks",onClick:()=>n("backlog"),children:"Buka"}),children:r.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10,marginTop:6},children:[r.jsx(kd,{icon:"lightbulb",label:"dari brief",value:m,tone:"var(--brass-600)"}),r.jsx(kd,{icon:"bug",label:"dari QA",value:p,tone:"var(--clay-500)"}),r.jsx(kd,{icon:"flame",label:"prioritas tinggi",value:_,tone:"var(--clay-500)"}),r.jsx(kd,{icon:"layers",label:"total spec",value:t.length,tone:"var(--wind-600)"})]})})]})]}),r.jsx("div",{style:{marginTop:20},children:r.jsx(be,{eyebrow:"workspace",title:"Aktivitas terbaru",children:y.length===0?r.jsx(ue,{kind:"empty",compact:!0,icon:"history",title:"Belum ada aktivitas",hint:"Sesi dan branch terakhir tiap project akan tampil di sini."}):r.jsx("div",{style:{marginTop:4},children:y.map((b,E)=>{const k=b.status==="running"?"var(--brass-500)":"var(--bone-400)";return r.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:12,padding:"9px 4px",borderBottom:"1px solid var(--border-hair)"},children:[r.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:k,flex:"0 0 auto"}}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12.5,color:"var(--text-strong)",width:120,flex:"0 0 auto",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:b.project}),r.jsx("span",{style:{fontSize:12.5,color:"var(--text-body)",flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:b.text}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:160},children:b.commit})]},E)})})})})]})}function Use(e){return e==="broken"?"err":e==="drift"?"warn":"ok"}function cA(e){return e.docStatus==="broken"?"high":e.docStatus==="drift"?"low":"none"}const zse={high:{bar:"var(--clay-500)",tint:"var(--clay-100)",text:"var(--clay-600)"},low:{bar:"var(--amber-500)",tint:"var(--amber-100)",text:"var(--amber-600)"}};function Hse({projects:e}){const t=e.filter(o=>o.session.status==="running").length,a=e.reduce((o,l)=>o+l.backlog,0),n=e.filter(o=>o.docStatus==="ok").length,i=e.filter(o=>cA(o)==="high").length,s=[{label:"Run aktif",value:t,dot:"var(--brass-500)"},{label:"Total di backlog",value:a,dot:"var(--wind-600)"},{label:"On convention",value:n+"/"+e.length,dot:"var(--leaf-600)"},{label:"Perlu perhatian",value:i,dot:"var(--clay-600)"}];return r.jsx("div",{className:"hn-stat-grid",style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:1,background:"var(--border-hair)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflow:"hidden",marginBottom:20},children:s.map(o=>r.jsxs("div",{style:{background:"var(--surface-card)",padding:"15px 18px"},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:7},children:[r.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:o.dot}}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:27,fontWeight:600,color:"var(--text-strong)",lineHeight:1},children:o.value})]}),r.jsx("div",{style:{fontSize:12,color:"var(--text-muted)",marginTop:6},children:o.label})]},o.label))})}function Gse({p:e,onOpen:t,onDelete:a}){const n=cA(e),i=e.session.status==="running",[s,o]=f.useState(!1);return r.jsxs("div",{className:"hn-project-row",onClick:t?()=>t(e):void 0,onMouseEnter:()=>o(!0),onMouseLeave:()=>o(!1),style:{display:"grid",gridTemplateColumns:"1.7fr 1.2fr 1.5fr 1.1fr 1.4fr",alignItems:"center",gap:12,padding:"11px 14px 11px 12px",borderBottom:"1px solid var(--border-hair)",borderLeft:`3px solid ${n==="none"?"transparent":zse[n].bar}`,cursor:t?"pointer":"default",background:s&&t?"var(--bone-100)":"transparent",transition:"background 120ms ease"},children:[r.jsx("div",{"data-label":"Project",style:{minWidth:0},children:r.jsxs("button",{type:"button",className:"hn-project-open","aria-label":`Buka project ${e.name}`,disabled:!t,onClick:l=>{l.stopPropagation(),t==null||t(e)},style:{all:"unset",display:"block",width:"100%",cursor:t?"pointer":"default"},children:[r.jsxs("span",{style:{display:"flex",alignItems:"center",gap:7},children:[r.jsx(Ie,{name:"box",size:13,color:"var(--text-muted)"}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:13.5,fontWeight:500,color:"var(--text-strong)"},children:e.name}),r.jsx(Ne,{tone:e.kind==="from-scratch"?"brass":"neutral",size:"sm",children:e.kind})]}),r.jsx("span",{style:{display:"block",fontSize:11.5,color:"var(--text-subtle)",marginTop:3,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.desc})]})}),r.jsx("div",{"data-label":"Status",children:r.jsx(Oa,{status:e.session.status,size:"sm",children:i&&e.session.phase?e.session.phase:void 0})}),r.jsx("div",{"data-label":"Docs · SoT",style:{paddingRight:8},children:r.jsx(Oc,{value:e.coverage,showLabel:!0,tone:Use(e.docStatus),size:"sm"})}),r.jsxs("div",{"data-label":"Backlog",style:{fontFamily:"var(--font-mono)",fontSize:11.5,color:"var(--text-muted)"},children:[e.backlog," · ",e.topStage]}),r.jsxs("div",{"data-label":"Aktivitas",style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"flex",alignItems:"center",gap:6,justifyContent:"space-between"},children:[r.jsx("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.activity}),a&&r.jsx("span",{onClick:l=>{l.stopPropagation(),a(e)},children:r.jsx(Gu,{size:"sm",variant:"ghost",icon:"trash-2",label:"Hapus project "+e.name})}),t&&r.jsx(Ie,{name:"chevron-right",size:14,color:"var(--text-subtle)"})]})]})}function qse({projects:e,onOpen:t,onDelete:a,pageSize:n,search:i="",dataVersion:s,onClearSearch:o}){const l=["Project","Status","Docs · SoT","Backlog","Aktivitas"],c="1.7fr 1.2fr 1.5fr 1.1fr 1.4fr",[d,h]=f.useState(e),[m,p]=f.useState(e.length),[g,_]=rt("projects","page",1,Hi),S=wh("projects","scroll",d.length>0);f.useEffect(()=>{_(1)},[i]),f.useEffect(()=>{var E;if(!n){h(e),p(e.length);return}let v=!0;const b=(E=F.listProjects)==null?void 0:E.call(F,{q:i||void 0,page:g,limit:n});return b==null||b.then(k=>{v&&(h(k.items),p(k.total))}).catch(()=>{}),()=>{v=!1}},[i,g,n,s,e]);const y=gi(m,g,n||m||1);return r.jsxs("div",{style:J0,children:[r.jsx("div",{style:Mr,children:r.jsx(Hse,{projects:e})}),d.length===0&&i?r.jsx(ue,{kind:"empty",icon:"search",title:`Tidak ada project cocok dengan “${i}”`,hint:"Coba kata kunci lain, atau kosongkan pencarian.",action:o,actionLabel:"Hapus pencarian",actionIcon:"x"}):r.jsxs(be,{padding:0,fill:!0,children:[r.jsx("div",{className:"hn-project-header",style:{...Mr,display:"grid",gridTemplateColumns:c,gap:12,padding:"10px 14px 10px 15px",borderBottom:"1px solid var(--border-hair)"},children:l.map(v=>r.jsx("span",{className:"hn-eyebrow",children:v},v))}),r.jsx("div",{ref:S,"data-testid":"projects-scroll",style:gc,children:d.map(v=>r.jsx(Gse,{p:v,onOpen:t,onDelete:a},v.id))}),n&&r.jsx(fi,{page:y.page,pageCount:y.pageCount,total:m,from:y.from,to:y.to,onPage:_,unit:"project"})]})]})}const $se=()=>({name:"",description:"",instructions:"",tools:[],model:"",mentions:[],runtime:"",enabled:!0}),Vse=e=>({name:e.name,description:e.description,instructions:e.instructions,tools:e.tools??[],model:e.model??"",mentions:e.mentions,runtime:e.runtime??"",enabled:e.enabled});function xd(e){if(!(e instanceof Mt))return(e==null?void 0:e.message)??"gagal";const t=e.detail??{};return Array.isArray(t.cycle)&&t.cycle.length?`Mention membentuk siklus di scope ${t.scope??"?"}: ${t.cycle.join(" → ")}`:Array.isArray(t.unknown)&&t.unknown.length?`Mention tak dikenal: ${t.unknown.join(", ")}`:Array.isArray(t.unknownTools)&&t.unknownTools.length?`Tool tak dikenal di mesin ini: ${t.unknownTools.join(", ")}`:typeof t.model=="string"?`Model "${t.model}" tak tersedia untuk runtime ${t.runtime??"warisi"}.`:typeof t.error=="string"?t.error:`Gagal (${e.status})`}function dA({projectId:e,onToast:t}){const[a,n]=f.useState(null),[i,s]=f.useState(null),[o,l]=f.useState(""),[c,d]=f.useState(null),[h,m]=f.useState(!1),p=f.useCallback(async()=>{try{n(await F.listCustomAgents(e??void 0))}catch(w){l(xd(w)),n([])}try{s(await F.getCustomAgentCatalog(e??void 0))}catch{s({tools:[],models:[],runtimes:[]})}},[e]);f.useEffect(()=>{p()},[p]);const g=(a??[]).filter(w=>w.name!==(c==null?void 0:c.draft.name)),_=!(c!=null&&c.draft.name)||V0.test(c.draft.name),S=(c==null?void 0:c.draft.runtime)||null,y=((i==null?void 0:i.tools)??[]).map(w=>w.id),v=((i==null?void 0:i.tools)??[]).map(w=>({value:w.id,label:w.label,...w.group==="mcp"?{group:"MCP"}:{}})),b=bv(S).filter(w=>!i||i.models.length===0||i.models.some(O=>O.id===w.id)).map(w=>({value:w.id,label:S?w.label:`${w.label} · ${w.runtime}`})),E=g.map(w=>({value:w.name,label:w.name})),k=((c==null?void 0:c.draft.tools)??[]).filter(w=>!y.includes(w)),T=((c==null?void 0:c.draft.mentions)??[]).filter(w=>!E.some(O=>O.value===w)),A=!!(c!=null&&c.draft.model)&&!b.some(w=>w.value===c.draft.model),M=k.length>0||T.length>0||A,x=w=>{if(!c)return;const H=w.includes(Os)&&!c.draft.tools.includes(Os)?[Os]:w.filter(N=>N!==Os);d({...c,draft:{...c.draft,tools:H}})},P=w=>{if(!c)return;const H=bv(w||null).map(N=>N.id).includes(c.draft.model)?c.draft.model:"";d({...c,draft:{...c.draft,runtime:w,model:H}})};async function R(){if(!c)return;const w=c.draft;m(!0),l("");try{const O={description:w.description,instructions:w.instructions,tools:w.tools.length?w.tools:null,model:w.model||null,mentions:w.mentions,runtime:w.runtime||null,enabled:w.enabled};c.id?await F.updateCustomAgent(c.id,O):await F.createCustomAgent({...O,name:w.name,projectId:e}),d(null),await p(),t==null||t(c.id?"Agen diperbarui":"Agen dibuat","ok")}catch(O){l(xd(O))}finally{m(!1)}}async function G(w,O){l("");try{await F.updateCustomAgent(w.id,{enabled:O}),await p()}catch(H){l(xd(H))}}async function j(w){l("");try{await F.deleteCustomAgent(w.id),await p(),t==null||t("Agen dihapus","ok")}catch(O){l(xd(O))}}return a===null?r.jsx(ue,{kind:"loading",title:"Memuat custom agent…"}):r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10},children:[r.jsx("div",{style:{flex:1,minWidth:0,fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:e?"Agen project ini, ditambah agen global yang berlaku di sini. Agen project menimpa agen global bernama sama.":"Agen global — tersedia di semua project. Satu project bisa menimpanya dengan agen bernama sama."}),r.jsx(B,{size:"sm",onClick:()=>{l(""),d({id:null,draft:$se()})},children:"Agen baru"})]}),o&&r.jsx(Nn,{tone:"err",children:o}),a.length===0&&!c&&r.jsx(ue,{kind:"empty",compact:!0,title:"Belum ada custom agent",hint:"Custom agent adalah persona yang bisa dipilih sesi claude & codex — misalnya peninjau keamanan atau penulis migration."}),a.map(w=>{const O=(w.tools??[]).includes(Os)?((i==null?void 0:i.tools)??[]).map(z=>z.id).filter(z=>z!==Os):w.tools,H=gD({tools:O,mentions:w.mentions}),N=!!(e&&w.inherited);return r.jsxs(be,{padding:14,children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:6},children:[r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:w.name}),N&&r.jsx(Ne,{tone:"neutral",size:"sm",children:"warisan global"}),!w.enabled&&r.jsx(Ne,{tone:"warn",size:"sm",children:"nonaktif"}),w.runtime&&r.jsx(Ne,{tone:"neutral",size:"sm","data-testid":`runtime-${w.name}`,children:w.runtime}),r.jsx("span",{style:{flex:1}}),r.jsx(ta,{checked:w.enabled,disabled:N,"aria-label":`Aktifkan ${w.name}`,onChange:z=>void G(w,z)}),r.jsx(B,{size:"sm",variant:"ghost",disabled:N,onClick:()=>{l(""),d({id:w.id,draft:Vse(w)})},children:"Ubah"}),r.jsx(B,{size:"sm",variant:"ghost",disabled:N,onClick:()=>void j(w),children:"Hapus"})]}),r.jsx("div",{style:{fontSize:"var(--text-xs)",color:"var(--text-muted)",marginBottom:6},children:w.description}),r.jsxs("div",{style:{display:"flex",gap:16,flexWrap:"wrap",fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:[r.jsxs("span",{"data-testid":`tools-${w.name}`,children:["Tools: ",H.join(", ")]}),r.jsxs("span",{"data-testid":`mentions-${w.name}`,children:["Mention: ",w.mentions.length?w.mentions.map(z=>`@${z}`).join(", "):"—"]}),w.model&&r.jsxs("span",{children:["Model: ",w.model]})]})]},w.id)}),c&&r.jsxs(be,{padding:16,children:[r.jsx(fe,{label:"Nama",hint:c.id?"Nama tak bisa diubah — hapus lalu buat baru (definisi ini menyeberang lewat sync).":"huruf kecil, angka, dan tanda hubung; minimal 2 karakter",children:r.jsx(je,{value:c.draft.name,"aria-label":"Nama",disabled:!!c.id,invalid:!_,placeholder:"mis. peninjau-keamanan",onChange:w=>d({...c,draft:{...c.draft,name:w.target.value}})})}),r.jsx(fe,{label:"Deskripsi",hint:"Kapan agen ini dipakai — inilah yang dibaca agen untuk MEMILIH.",children:r.jsx(je,{value:c.draft.description,"aria-label":"Deskripsi",placeholder:"mis. Dipakai saat meninjau perubahan yang menyentuh auth",onChange:w=>d({...c,draft:{...c.draft,description:w.target.value}})})}),r.jsx(fe,{label:"Instruksi",hint:"System prompt agen.",children:r.jsx(Ta,{value:c.draft.instructions,"aria-label":"Instruksi",rows:6,placeholder:"mis. Kamu peninjau keamanan. Baca diff, laporkan temuan berurut dari yang paling berbahaya, sebut file:line.",onChange:w=>d({...c,draft:{...c.draft,instructions:w.target.value}})})}),r.jsx(fe,{label:"Tools",hint:`Kosongkan untuk memakai default: ${hM.join(", ")}. Alat delegasi (Task) diatur otomatis dari Mention.`,children:r.jsx(Uv,{"aria-label":"Tools",options:v,value:c.draft.tools,invalidValues:k,onChange:x,placeholder:"Pilih tools…",searchPlaceholder:"mis. Read atau Bash"})}),r.jsx(fe,{label:"Runtime agent",hint:"Mesin sesi yang memakai agen ini. Kosongkan untuk ikut sesi induk — dipakai sesi claude maupun codex.",children:r.jsx(xe,{"aria-label":"Runtime agent",value:c.draft.runtime,options:[{value:"",label:"Ikut sesi induk"},...((i==null?void 0:i.runtimes)??[]).map(w=>({value:w.id,label:w.label}))],onChange:w=>P(w.target.value)})}),r.jsx(fe,{label:"Model",hint:"Kosongkan untuk mewarisi model sesi.",children:r.jsx(xe,{"aria-label":"Model",value:c.draft.model,invalid:A,options:[{value:"",label:"Ikut sesi induk"},...b,...A?[{value:c.draft.model,label:`⚠ ${c.draft.model} — tak ada di katalog`}]:[]],onChange:w=>d({...c,draft:{...c.draft,model:w.target.value}})})}),r.jsx(fe,{label:"Mention",hint:"Agen yang boleh dipanggil agen ini. Graf mention wajib asiklik — server menolak yang membentuk lingkaran.",children:r.jsx(Uv,{"aria-label":"Mention",options:E,value:c.draft.mentions,invalidValues:T,onChange:w=>d({...c,draft:{...c.draft,mentions:w}}),placeholder:"Pilih agen…",searchPlaceholder:"mis. peninjau-keamanan",emptyText:"Belum ada agen lain."})}),M&&r.jsx(Nn,{tone:"warn",children:"Ada nilai yang tak ada di katalog mesin ini (ditandai ⚠). Buang dulu sebelum menyimpan — server menolak nilai yang tak dikenal."}),r.jsxs("div",{style:{display:"flex",gap:8},children:[r.jsx(B,{onClick:()=>void R(),loading:h,disabled:!_||M,children:"Simpan"}),r.jsx(B,{variant:"ghost",onClick:()=>{d(null),l("")},children:"Batal"})]})]})]})}const Yse=[{value:"off",label:"Tanpa auto-merge (default)"},{value:"default-branch",label:"Auto-merge ke default branch repo"},{value:"branch",label:"Auto-merge ke branch tujuan…"}],Wse=[{value:"local",label:"Branch lokal (perbarui ref di checkout ini)"},{value:"origin",label:"Origin (push ke remote)"}];function Kse({p:e,onToast:t,onProjectChanged:a}){const n=e.autoMerge??null,[i,s]=f.useState(n??po),[o,l]=f.useState({local:[],origin:[],def:null}),[c,d]=f.useState(!1),h=e.binding??e.repoDir??null;f.useEffect(()=>{s(n??po)},[n]),f.useEffect(()=>{let _=!0;return F.listBranches(e.id).then(S=>{_&&l({local:S.branches,origin:S.remotes,def:S.defaultBranch??null})}).catch(()=>{_&&l({local:[],origin:[],def:null})}),()=>{_=!1}},[e.id]);const m=o[i.dest==="origin"?"origin":"local"],p=_=>S=>s(y=>({...y,[_]:S}));async function g(){d(!0);try{await F.updateProject(e.id,{autoMerge:i.mode==="off"?null:i}),t("Kebijakan auto-merge disimpan","ok","git-merge"),await(a==null?void 0:a(e.id))}catch(_){t(`Gagal menyimpan: ${_.message}`,"err","x-circle")}finally{d(!1)}}return r.jsxs(be,{eyebrow:"integrasi",title:"Auto-merge saat sesi selesai",actions:r.jsx(B,{size:"sm",leftIcon:"check",disabled:c||!h,onClick:g,children:"Simpan"}),children:[r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Saat sebuah backlog item mencapai ",r.jsx("b",{children:"Selesai"}),", hanoman menggabungkan branch kerjanya (",r.jsx("code",{children:"hanoman/<spec>"}),") ke branch tujuan. Merge saja — tak pernah rebase, tak pernah force-push. Konflik tidak menghapus apa pun: branch kerja tetap utuh dan kamu dapat notifikasi berisi alasannya. Item bisa menimpa setelan ini satu per satu dari Backlog."]}),!h&&r.jsxs("div",{style:{fontSize:12.5,color:"var(--status-warn, var(--text-muted))",marginBottom:12},children:["Project ini belum di-bind ke checkout lokal — atur ",r.jsx("b",{children:"repoDir"})," dulu (Edit project) sebelum menyalakan auto-merge."]}),r.jsx("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:12,flexWrap:"wrap"},children:r.jsx(Ne,{tone:n&&n.mode!=="off"?"ok":"neutral",size:"sm",children:iM(n??po)})}),r.jsxs("div",{style:{display:"grid",gap:10},children:[r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Mode"}),r.jsx(xe,{size:"sm","aria-label":"Mode auto-merge",value:i.mode,disabled:!h,onChange:_=>p("mode")(_.target.value),options:Yse})]}),i.mode!=="off"&&r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Tujuan"}),r.jsx(xe,{size:"sm","aria-label":"Tujuan",value:i.dest,disabled:!h,onChange:_=>p("dest")(_.target.value),options:Wse})]}),i.mode==="default-branch"&&r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-subtle)"},children:["Default branch repo saat ini: ",r.jsx("b",{children:o.def??"— tak terbaca"}),". Diresolve ulang tiap kali auto-merge berjalan, jadi mengganti default branch repo tak menyisakan setelan basi."]}),i.mode==="branch"&&r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Branch tujuan"}),r.jsx(xe,{size:"sm","aria-label":"Branch tujuan",value:i.branch??"",disabled:!h||!m.length,onChange:_=>p("branch")(_.target.value||null),options:[{value:"",label:"Pilih branch…"},...m.map(_=>({value:_,label:_}))]})]}),i.mode!=="off"&&r.jsx(gn,{"aria-label":"Hapus branch kerja setelah merge sukses",checked:i.deleteBranch,label:"Hapus branch kerja setelah merge sukses",onChange:()=>p("deleteBranch")(!i.deleteBranch)})]})]})}const Qse=e=>e==="broken"?"err":e==="drift"?"warn":"ok";function Zse({p:e,onToast:t,onProjectChanged:a}){const[n,i]=f.useState(e.helpEnabled),[s,o]=f.useState(!1),l=`${window.location.origin}/help/${encodeURIComponent(e.id)}`;async function c(){o(!0);try{await F.enableHelpCenter(e.id),i(!0),t("Help Center aktif","ok","inbox"),await(a==null?void 0:a(e.id))}catch{t("Gagal mengaktifkan Help Center","err","x-circle")}finally{o(!1)}}async function d(){if(window.confirm(`Nonaktifkan Help Center project "${e.name}"? Link publik berhenti menerima keluhan baru (tiket lama tetap ada).`)){o(!0);try{await F.disableHelpCenter(e.id),i(!1),t("Help Center nonaktif","ok","inbox"),await(a==null?void 0:a(e.id))}catch{t("Gagal menonaktifkan Help Center","err","x-circle")}finally{o(!1)}}}return r.jsxs(be,{eyebrow:"help center",title:"Link publik keluhan",actions:n?r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"ban",onClick:d,disabled:s,children:"Nonaktifkan"}):r.jsx(B,{size:"sm",leftIcon:"inbox",onClick:c,disabled:s,children:"Aktifkan"}),children:[r.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:10,lineHeight:1.5},children:"Saat aktif, sebar link ini agar pengguna project melapor keluhan tanpa login. Keluhan masuk ke antrean Triase."}),r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[r.jsx(Ne,{tone:n?"ok":"neutral",size:"sm",children:n?"aktif":"nonaktif"}),n&&l&&r.jsxs(r.Fragment,{children:[r.jsx("code",{style:{fontFamily:"var(--font-mono)",fontSize:12.5,color:"var(--text-body)",wordBreak:"break-all"},children:l}),r.jsx(B,{size:"sm",leftIcon:"copy",onClick:()=>{var h;(h=navigator.clipboard)==null||h.writeText(l),t("Link disalin","ok","copy")},children:"Salin"})]})]})]})}function ol({label:e,value:t,mono:a}){return r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",children:e}),r.jsx("div",{style:{marginTop:4,fontSize:12.5,color:"var(--text-body)",fontFamily:a?"var(--font-mono)":"var(--font-ui)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:t})]})}function Ps({icon:e,title:t,hint:a,onClick:n}){return r.jsx(be,{padding:0,children:r.jsxs("button",{type:"button",onClick:n,style:{display:"flex",alignItems:"center",gap:12,width:"100%",padding:"14px 16px",cursor:"pointer",textAlign:"left",border:"none",background:"transparent",color:"inherit"},children:[r.jsx(Ie,{name:e,size:16,color:"var(--text-muted)"}),r.jsxs("div",{style:{flex:1,minWidth:0},children:[r.jsx("div",{style:{fontSize:13.5,fontWeight:500,color:"var(--text-strong)"},children:t}),r.jsx("div",{style:{fontSize:11.5,color:"var(--text-subtle)",marginTop:2},children:a})]}),r.jsx(Ie,{name:"chevron-right",size:14,color:"var(--text-subtle)"})]})})}function Xse({p:e,onEdit:t,onGotoDocs:a,onGotoTerminal:n,onGotoBacklog:i,onGotoChangelog:s,onDelete:o,onReverse:l,onScaffold:c,onToast:d,onProjectChanged:h}){return r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:20},children:[r.jsxs(be,{children:[r.jsxs("div",{className:"hn-stack-mobile",style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:16},children:[r.jsxs("div",{style:{minWidth:0},children:[r.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",alignItems:"center",gap:8},children:[r.jsx(Ie,{name:"box",size:15,color:"var(--text-muted)"}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:22,fontWeight:600,color:"var(--text-strong)"},children:e.name}),r.jsx(Ne,{tone:e.kind==="from-scratch"?"brass":"neutral",size:"sm",children:e.kind}),r.jsx(Oa,{status:e.session.status,size:"sm",children:e.session.phase??void 0})]}),r.jsx("div",{style:{fontSize:12.5,color:"var(--text-subtle)",marginTop:6},children:e.desc})]}),r.jsxs("div",{className:"hn-row-actions",style:{display:"flex",gap:8,flex:"0 0 auto"},children:[r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"pencil",onClick:t,children:"Edit project"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"trash-2",onClick:o,children:"Hapus project"})]})]}),r.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:16,marginTop:20},children:[r.jsx(ol,{label:"ID",value:e.id,mono:!0}),r.jsx(ol,{label:e.binding?"Repo · mesin ini":"Repo",value:(e.binding??e.repoDir)||"—",mono:!0}),r.jsx(ol,{label:"Git remote",value:e.gitRemote||"—",mono:!0}),r.jsx(ol,{label:"Stack",value:e.stack||"—"}),r.jsx(ol,{label:"Backlog terbuka",value:`${e.backlog} · ${e.topStage}`})]}),r.jsxs("div",{style:{marginTop:18},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Docs · SoT"}),r.jsx(Oc,{value:e.coverage,showLabel:!0,tone:Qse(e.docStatus),size:"sm"})]})]}),r.jsx(Zse,{p:e,onToast:d,onProjectChanged:h}),r.jsx(Kse,{p:e,onToast:d,onProjectChanged:h}),r.jsxs(be,{eyebrow:"agen",title:"Custom agent — project ini",children:[r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Persona khusus project ini, ditambah agen global yang berlaku di sini. Agen project",r.jsx("b",{children:" menimpa"})," agen global bernama sama — termasuk untuk mematikannya di project ini saja."]}),r.jsx(dA,{projectId:e.id,onToast:d})]}),r.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(190px, 1fr))",gap:12},children:[r.jsx(Ps,{icon:"book-open",title:"Source of Truth",hint:"baca & sunting docs",onClick:a}),r.jsx(Ps,{icon:"terminal",title:"Buka terminal",hint:"sesi claude project ini",onClick:n}),r.jsx(Ps,{icon:"list-checks",title:"Lihat backlog",hint:`${e.backlog} spec terbuka`,onClick:i}),r.jsx(Ps,{icon:"megaphone",title:"Changelog",hint:"ringkasan rilis untuk pemakai",onClick:s}),l&&r.jsx(Ps,{icon:"radar",title:"Reverse docs",hint:"susun Source of Truth dari kode",onClick:l}),c&&r.jsx(Ps,{icon:"sparkles",title:"Scaffold docs",hint:"susun Source of Truth dari ide",onClick:c})]})]})}const Jse={audit:"Audit",spec:"Spec",plan:"Plan",objective:"Objective",brainstorm:"Brainstorm",other:"Lainnya"};function uA({specId:e,onClose:t}){const[a,n]=f.useState(null),[i,s]=f.useState(!1),[o,l]=f.useState(""),[c,d]=f.useState("files"),[h,m]=f.useState({});f.useEffect(()=>{let y=!0;return n(null),s(!1),l(""),m({}),d("files"),F.getSpecDocs(e).then(v=>{y&&(n(v.files),v.files[0]&&l(v.files[0].path))}).catch(()=>{y&&s(!0)}),()=>{y=!1}},[e]),f.useEffect(()=>{if(!o||o in h)return;let y=!0;return F.getSpecDocFile(e,o).then(v=>{y&&m(b=>({...b,[o]:v.content}))}).catch(()=>{y&&m(v=>({...v,[o]:null}))}),()=>{y=!1}},[o,e,h]);const p=a===null&&!i,g=!!o&&!(o in h),_=o?h[o]===null:!1,S=[];for(const y of a??[]){const v=S[S.length-1];v&&v.kind===y.kind?v.items.push(y):S.push({kind:y.kind,items:[y]})}return r.jsx(Tt,{open:!0,title:"Dokumen backlog item",eyebrow:e,icon:"file-text",onClose:t,width:900,fillHeight:!0,children:i?r.jsx(ue,{kind:"error",title:"Gagal memuat daftar dokumen",hint:e}):p?r.jsx(ue,{kind:"loading",title:"Memuat dokumen…",hint:e}):a.length?r.jsx(No,{ariaLabel:"Panel dokumen backlog",active:c,onActiveChange:y=>d(y),masterWidth:240,className:"hn-workspace-panels",style:{height:"100%"},panels:[{id:"files",label:"Files",className:"hn-panel-flex",content:r.jsx("div",{style:{overflow:"auto",borderRight:"1px solid var(--border-hair)",paddingRight:8},children:S.map(y=>r.jsxs("div",{style:{marginBottom:10},children:[r.jsx("div",{className:"hn-eyebrow",style:{padding:"4px 6px",color:"var(--text-subtle)"},children:Jse[y.kind]??y.kind}),y.items.map(v=>{const b=v.path===o;return r.jsxs("button",{onClick:()=>{l(v.path),d("preview")},style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"6px 8px",borderRadius:"var(--radius-sm)",border:"none",cursor:"pointer",textAlign:"left",background:b?"var(--brass-100)":"transparent"},children:[r.jsx(Ie,{name:"file-text",size:13,color:b?"var(--brass-700)":"var(--text-subtle)"}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11.5,color:b?"var(--brass-700)":"var(--text-body)",fontWeight:b?600:400,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:v.name})]},v.path)})]},y.kind))})},{id:"preview",label:"Preview",className:"hn-panel-flex",content:r.jsxs("div",{style:{display:"flex",flexDirection:"column",minHeight:0},children:[r.jsx("div",{style:{display:"flex",justifyContent:"flex-end",paddingBottom:6,borderBottom:"1px solid var(--border-hair)",marginBottom:8},children:r.jsx(Do,{href:y=>F.specDocDownloadUrl(e,o,y),disabled:!o||g||_})}),r.jsx("div",{"data-testid":"doc-preview-scroll",style:{flex:"1 1 auto",minHeight:0,overflow:"auto",padding:"0 8px 16px"},children:g?r.jsx(ue,{kind:"loading",title:"Memuat…",hint:o}):_?r.jsx(ue,{kind:"error",title:"Gagal memuat berkas",hint:o}):r.jsx(Ar,{text:h[o]??"",name:o})})]})}]}):r.jsx(ue,{kind:"empty",icon:"file-text",title:"Belum ada dokumen untuk item ini",hint:"Jalankan item ini agar agent menulis audit/spec/plan."})})}function Wf({projectId:e,ownBranch:t,eyebrow:a,onClose:n,onIntegrate:i}){const[s,o]=f.useState({local:[],origin:[]}),[l,c]=f.useState(""),d=t;f.useEffect(()=>{let p=!0;return F.listBranches(e).then(g=>{p&&o({local:g.branches.filter(_=>_!==d),origin:g.remotes.filter(_=>_!==d)})}).catch(()=>{p&&o({local:[],origin:[]})}),()=>{p=!1}},[e,d]);const h=[{value:"",label:"Pilih target…"},...s.local.map(p=>({value:`local:${p}`,label:`${p} (lokal)`})),...s.origin.map(p=>({value:`origin:${p}`,label:`origin/${p}`}))],m=p=>{l&&i(p,l)};return r.jsxs(Tt,{open:!0,title:"Rebase / Merge",eyebrow:`${a} · ${d}`,icon:"git-merge",onClose:n,children:[r.jsxs("div",{style:{fontSize:13,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Rebase menata ulang branch di atas target (force-push balik ke branch itu). Merge menggabungkan branch ke target. Bila ada konflik, sesi agen membereskannya di Terminal — agen, model & effort-nya diatur di ",r.jsx("b",{children:"Settings → Model sesi → Konflik rebase & merge"})," ","(SPEC-383/ADR-0081); selama kartu itu mati, ia mengikuti default global."]}),r.jsxs("div",{style:{marginBottom:16},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Target"}),r.jsx(xe,{size:"sm","aria-label":"Target",value:l,disabled:h.length===1,onChange:p=>c(p.target.value),options:h})]}),r.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end"},children:[r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"git-branch",disabled:!l,onClick:()=>m("rebase"),children:"Rebase"}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"git-merge",disabled:!l,onClick:()=>m("merge"),children:"Merge"})]})]})}function eoe(e){return new Date(e.localUpdatedAt)>=new Date(e.serverUpdatedAt)?"local":"server"}function toe(e){try{return JSON.stringify(e,null,2)}catch{return String(e)}}function aoe({open:e,onClose:t,onResolved:a}){const[n,i]=f.useState([]),[s,o]=f.useState(null),l=f.useCallback(async()=>{try{i((await F.listConflicts()).conflicts)}catch{i([])}},[]);f.useEffect(()=>{e&&l()},[e,l]);async function c(d,h){o(`${d.entity}:${d.recordId}`);try{await F.resolveConflict(d.entity,d.recordId,h),await l(),a()}finally{o(null)}}return r.jsxs(Tt,{open:e,title:"Rekonsil konflik sync",eyebrow:"SPEC-270",icon:"git-merge",width:720,onClose:t,children:[n.length===0&&r.jsx("div",{style:{fontSize:13.5,color:"var(--text-muted)"},children:"Tak ada konflik. Semua sinkron."}),n.map(d=>{const h=eoe(d),m=`${d.entity}:${d.recordId}`;return r.jsxs("div",{style:{border:"1px solid var(--line)",borderRadius:8,padding:12,marginBottom:12},children:[r.jsxs("div",{style:{fontSize:12,color:"var(--text-muted)",marginBottom:6},children:[d.entity," · ",d.recordId," · ",r.jsxs("span",{"data-testid":"default-side",children:["default: ",h==="local"?"Lokal":"Server"," (updatedAt terbaru)"]})]}),r.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10},children:[r.jsx(yb,{label:"Lokal",data:d.localData,at:d.localUpdatedAt,ver:d.localVersion,active:h==="local"}),r.jsx(yb,{label:"Server",data:d.serverData,at:d.serverUpdatedAt,ver:d.serverVersion,active:h==="server"})]}),r.jsxs("div",{style:{display:"flex",gap:8,marginTop:10,justifyContent:"flex-end"},children:[r.jsx(B,{size:"sm",variant:h==="local"?"primary":"secondary",disabled:s===m,onClick:()=>c(d,"local"),children:"Pakai Lokal"}),r.jsx(B,{size:"sm",variant:h==="server"?"primary":"secondary",disabled:s===m,onClick:()=>c(d,"server"),children:"Pakai Server"})]})]},m)})]})}function yb({label:e,data:t,at:a,ver:n,active:i}){return r.jsxs("div",{style:{border:i?"1px solid var(--brass)":"1px solid var(--line)",borderRadius:6,padding:8},children:[r.jsxs("div",{style:{fontSize:12,fontWeight:600},children:[e," · v",n]}),r.jsx("div",{style:{fontSize:11,color:"var(--text-muted)",marginBottom:4},children:new Date(a).toLocaleString()}),r.jsx("pre",{style:{fontSize:11,whiteSpace:"pre-wrap",margin:0,maxHeight:200,overflow:"auto"},children:toe(t)})]})}let Mp=null;function noe(){const[e,t]=f.useState(!1);return f.useEffect(()=>{Mp||(Mp=(async()=>{var n;try{return((n=(await F.getConfig()).sync)==null?void 0:n.running)??!1}catch{return!1}})());let a=!0;return Mp.then(n=>{a&&t(n)}),()=>{a=!1}},[]),e}function hA({onDone:e,onToast:t}){const a=noe(),[n,i]=f.useState(""),[s,o]=f.useState(!1);if(!a)return null;async function l(c){i(c?"full":"once");try{const d=c?await F.syncNow({full:!0}):await F.syncNow();d.ok?t(`Sinkron: ↓${d.pulled??0} ↑${d.pushed??0}${d.conflicts?` · ${d.conflicts} konflik`:""}`,d.conflicts?"warn":"ok",d.conflicts?"triangle-alert":"check"):t("Instance ini hub — tak ada sync manual","info","info"),d.ok&&d.conflicts&&o(!0),e()}catch{t("Gagal sync","err","x-circle")}finally{i("")}}return r.jsxs(r.Fragment,{children:[r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"rotate-ccw",onClick:()=>l(!1),disabled:n!=="",children:n==="once"?"Menyinkron…":"Sync"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"history",onClick:()=>l(!0),disabled:n!=="",title:"Tarik ulang seluruh feed dari awal — untuk data lama yang tak ikut tersinkron",children:n==="full"?"Menarik ulang…":"Tarik ulang"}),r.jsx(aoe,{open:s,onClose:()=>o(!1),onResolved:e})]})}const Sb={qa:{label:"QA finding",icon:"bug",tone:"err",color:"var(--clay-500)"},audit:{label:"Audit",icon:"search",tone:"info",color:"var(--wind-600)"},brief:{label:"feature brief",icon:"lightbulb",tone:"brass",color:"var(--brass-500)"},goal:{label:"Goal",icon:"target",tone:"brass",color:"var(--brass-600)"},help:{label:"Help Center",icon:"life-buoy",tone:"info",color:"var(--wind-500)"}},Sn=e=>Sb[e]??Sb.brief,ioe=Rc.options.map(e=>({value:e,label:Sn(e).label})),pA=[["context","Konteks","mis. operator harus membuka tiga layar untuk tahu sesi mana yang menunggu"],["outcome","Outcome","mis. satu badge di Overview menunjukkan jumlah sesi yang menunggu"],["constraints","Constraints","mis. reuse queue yang ada"]],mA=[["goal","Goal","mis. p95 GET /api/specs di bawah 200 ms"],["done","Selesai bila","mis. output benchmark menunjukkan < 200 ms"],["constraints","Batasan","mis. tanpa cache eksternal"]],_A=[["severity","Severity",""],["steps","Langkah reproduksi",`1. Buka …
7483
+ `+(e||"")+"\n```";return Sse(a)}function Ar({text:e,name:t}){return r.jsx("div",{className:"hn-md",dangerouslySetInnerHTML:{__html:bse(e,t)}})}function Do({href:e,disabled:t=!1,size:a="sm"}){return t?null:r.jsxs("div",{style:{display:"flex",gap:4},children:[r.jsx(B,{as:"a",href:e("md"),download:!0,size:a,variant:"ghost",leftIcon:"download",title:"Unduh sumber Markdown","aria-label":"Unduh .md",children:".md"}),r.jsx(B,{as:"a",href:e("pdf"),download:!0,size:a,variant:"ghost",leftIcon:"file-down",title:"Unduh sebagai PDF","aria-label":"Unduh .pdf",children:".pdf"})]})}function p2({path:e,text:t,eyebrow:a,download:n,onClose:i}){const s=e.slice(e.lastIndexOf("/")+1)||e;return r.jsx(Tt,{open:!0,title:s,eyebrow:a??e,icon:"book-open",onClose:i,width:980,fillHeight:!0,children:r.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},children:[n&&r.jsx("div",{style:{display:"flex",justifyContent:"flex-end",paddingBottom:6,borderBottom:"1px solid var(--border-hair)",marginBottom:8},children:r.jsx(Do,{href:n})}),r.jsx("div",{"data-testid":"doc-preview-scroll",style:{flex:"1 1 0",minHeight:0,overflow:"auto",padding:"0 4px 8px"},children:t?r.jsx(Ar,{text:t,name:e}):r.jsx(ue,{kind:"empty",icon:"file-text",title:"Berkas kosong",hint:e})})]})})}function Mh({screen:e,active:t,onReset:a,label:n="Reset tampilan"}){return r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[t>0&&r.jsxs(Ne,{tone:"warn",size:"sm",icon:"filter",children:[t," filter aktif"]}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"rotate-ccw",disabled:t===0,onClick:()=>{qie(e),a==null||a()},children:n})]})}function Ku(e){return e==="codex"?mo:F0}function m2(e,t){return e==="codex"?qs(t):rM}function Vf(e,t){const a=e[t];return{model:a.model,effort:t==="codex"?wn(a.model,a.effort):a.effort}}function Ese({needsSetup:e,onDone:t}){const[a,n]=f.useState(""),[i,s]=f.useState(""),[o,l]=f.useState(""),[c,d]=f.useState(!1),[h,m]=f.useState(""),p=/\S+@\S+\.\S+/.test(a)&&i.length>=(e?8:1)&&(!e||o.trim().length>0);async function g(){if(!(!p||c)){d(!0),m("");try{const{user:_}=await(e?F.setup({email:a,password:i,setupToken:o.trim()}):F.login({email:a,password:i}));t(_)}catch(_){m(e?_ instanceof Mt&&_.status===409?"Sudah ada akun — silakan masuk.":"Gagal membuat akun. Password minimal 8 karakter.":"Email atau password salah."),d(!1)}}}return r.jsx("div",{"data-testid":"auth-scroll",className:"hn-dynamic-viewport",style:{minHeight:"100dvh",height:"100dvh",display:"flex",overflowY:"auto",background:"var(--bone-100)",boxSizing:"border-box",padding:"max(24px, var(--safe-top)) max(16px, var(--safe-right)) max(24px, var(--safe-bottom)) max(16px, var(--safe-left))"},children:r.jsxs("div",{style:{width:"100%",maxWidth:380,margin:"auto"},children:[r.jsx("div",{style:{display:"flex",justifyContent:"center",marginBottom:20},children:r.jsx(cie,{})}),r.jsxs(be,{eyebrow:e?"hanoman · setup":"hanoman · masuk",title:e?"Buat akun pertama":"Masuk",children:[r.jsx(PM,{id:"PST-001",priority:!0,style:{width:"100%",maxHeight:184,marginBottom:14,borderRadius:"var(--radius-md)"}}),r.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:16,lineHeight:1.5},children:e?"Belum ada akun. Akun pertama ini yang bisa mengundang user lain.":"Masuk dengan email dan password."}),r.jsxs("form",{onSubmit:_=>{_.preventDefault(),g()},children:[r.jsx(fe,{label:"Email",children:r.jsx(je,{type:"email",autoComplete:"username",value:a,placeholder:"kamu@nafanesia.id",onChange:_=>n(_.target.value),style:{width:"100%"}})}),r.jsx(fe,{label:"Password",hint:e?"minimal 8 karakter":void 0,children:r.jsx(je,{type:"password",autoComplete:e?"new-password":"current-password",value:i,placeholder:"••••••••",onChange:_=>s(_.target.value),style:{width:"100%"}})}),e&&r.jsx(fe,{label:"Setup token",hint:"baca setup.token di HANOMAN_HOME pada host server",children:r.jsx(je,{type:"password",autoComplete:"off",value:o,onChange:_=>l(_.target.value),style:{width:"100%"}})}),h&&r.jsx("div",{style:{fontSize:12.5,color:"var(--status-err)",marginBottom:12},children:h}),r.jsx(B,{type:"submit",leftIcon:e?"user-plus":"log-in",disabled:!p||c,style:{width:"100%",justifyContent:"center"},children:c?"Memproses…":e?"Buat akun & masuk":"Masuk"})]})]})]})})}async function rl(e){const t=await fetch(e,{headers:{"content-type":"application/json"}});if(!t.ok)throw new Mt(t.status,`GET ${e} → ${t.status}`);return t.json()}const sl=e=>`/api/portal/projects/${encodeURIComponent(e)}`,hb=({page:e,limit:t})=>`?page=${e}&limit=${t}`,Gr={listProjects:()=>rl("/api/portal/projects"),listBacklog:(e,t)=>rl(`${sl(e)}/backlog${hb(t)}`),getSpec:(e,t)=>rl(`${sl(e)}/backlog/${encodeURIComponent(t)}`),listTickets:(e,t)=>rl(`${sl(e)}/tickets${hb(t)}`),getTicket:(e,t)=>rl(`${sl(e)}/tickets/${encodeURIComponent(t)}`),createTicket:async(e,t)=>{const a=`${sl(e)}/tickets`,n=await fetch(a,{method:"POST",body:t});if(!n.ok)throw new Mt(n.status,`POST ${a} → ${n.status}`);return n.json()},logout:async()=>{const e=await fetch("/api/auth/logout",{method:"POST"});if(!e.ok)throw new Mt(e.status,`POST /api/auth/logout → ${e.status}`)}},kse={"Sedang ditinjau":"queued",Diterima:"awaiting","Sedang dikerjakan":"running",Selesai:"done",Ditutup:"failed"},xse={brainstorming:"queued",objective:"queued","spec-ready":"queued",planned:"queued",executing:"running",done:"done"},pb=e=>kse[e]??"idle",mb=e=>xse[e]??"idle",Tse={bug:"Bug",fitur:"Permintaan fitur",pertanyaan:"Pertanyaan",lainnya:"Lainnya"},wp=3;function Cse({projects:e,activeId:t,onCancel:a,onSent:n}){const[i,s]=f.useState(t),[o,l]=f.useState(Of.options[0]),[c,d]=f.useState(""),[h,m]=f.useState(""),[p,g]=f.useState([]),[_,S]=f.useState(!1),[y,v]=f.useState(null),b=async()=>{v(null),S(!0);try{const E=new FormData;E.set("category",o),E.set("title",c),E.set("detail",h);for(const k of p.slice(0,wp))E.append("files",k,k.name);await Gr.createTicket(i,E),n(i)}catch{v("Gagal mengirim keluhan. Coba lagi sebentar.")}finally{S(!1)}};return r.jsxs(Tt,{open:!0,title:"Kirim keluhan",icon:"send",eyebrow:"help desk",onClose:a,children:[r.jsx(fe,{label:"Project",children:r.jsx(xe,{"aria-label":"Project",value:i,onChange:E=>s(E.target.value),options:e.map(E=>({value:E.id,label:E.name})),style:{width:"100%"}})}),r.jsx(fe,{label:"Kategori",children:r.jsx(xe,{"aria-label":"Kategori",value:o,onChange:E=>l(E.target.value),options:Of.options.map(E=>({value:E,label:Tse[E]??E})),style:{width:"100%"}})}),r.jsx(fe,{label:"Judul",children:r.jsx("input",{"aria-label":"Judul",value:c,onChange:E=>d(E.target.value),maxLength:200,placeholder:"mis. Tombol Simpan tak berfungsi di HP",style:wse})}),r.jsx(fe,{label:"Detail",children:r.jsx(Ta,{"aria-label":"Detail",value:h,onChange:E=>m(E.target.value),rows:5,placeholder:"mis. Buka halaman Pesanan di HP, tekan Simpan — layar diam dan datanya tak tersimpan."})}),r.jsx(fe,{label:"Lampiran gambar",hint:`Opsional, maksimal ${wp} berkas PNG/JPEG/WebP.`,children:r.jsx("input",{"aria-label":"Lampiran gambar",type:"file",accept:"image/png,image/jpeg,image/webp",multiple:!0,onChange:E=>g(Array.from(E.target.files??[]).slice(0,wp))})}),y&&r.jsx("div",{style:{color:"var(--clay-600)",fontSize:13,marginBottom:8},children:y}),r.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",marginTop:8},children:[r.jsx(B,{size:"sm",variant:"secondary",onClick:a,children:"Batal"}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"send",disabled:_||!c.trim()||!h.trim(),onClick:b,children:"Kirim"})]})]})}const wse={display:"block",width:"100%",boxSizing:"border-box",padding:"9px 11px",border:"1px solid var(--border-strong)",borderRadius:"var(--radius-sm)",background:"var(--surface-card)",color:"var(--text-strong)",fontSize:13,fontFamily:"var(--font-ui)"},Ls=e=>e?new Date(e).toLocaleDateString("id-ID",{day:"numeric",month:"short",year:"numeric"}):"—",_b={brainstorming:"Dirumuskan",objective:"Dirumuskan","spec-ready":"Disiapkan",planned:"Direncanakan",executing:"Sedang dikerjakan",done:"Selesai"},Qu=20,Ed={items:[],total:0,page:1,pageSize:Qu};function gb({total:e,page:t,onPage:a,unit:n}){const i=gi(e,t,Qu);return r.jsx("div",{style:{marginTop:14,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflow:"hidden"},children:r.jsx(fi,{page:i.page,pageCount:i.pageCount,total:e,from:i.from,to:i.to,onPage:a,unit:n})})}function Rse({user:e,onLoggedOut:t}){const[a,n]=f.useState(null),[i,s]=f.useState(null),[o,l]=f.useState("backlog"),[c,d]=f.useState(Ed),[h,m]=f.useState(Ed),[p,g]=f.useState(1),[_,S]=f.useState(1),[y,v]=f.useState(0),[b,E]=f.useState(null),[k,T]=f.useState(null),[A,M]=f.useState(!1),[x,P]=f.useState(!1);f.useEffect(()=>{Gr.listProjects().then(w=>{n(w.items),s(O=>{var H;return O??((H=w.items[0])==null?void 0:H.id)??null})}).catch(()=>{n([]),M(!0)})},[]);const R=f.useRef(0),G=f.useCallback((w,O,H)=>{const N=++R.current;Promise.all([Gr.listBacklog(w,{page:O,limit:Qu}),Gr.listTickets(w,{page:H,limit:Qu})]).then(([z,U])=>{N===R.current&&(d(z),m(U))}).catch(()=>{N===R.current&&(d(Ed),m(Ed))})},[]);f.useEffect(()=>{i&&G(i,p,_)},[i,p,_,y,G]),f.useEffect(()=>{g(1),S(1)},[i,o]);const j=async()=>{try{await Gr.logout()}catch{}finally{t()}};return r.jsxs("div",{"data-testid":"portal-root",className:"hn-dynamic-viewport",style:{height:"100dvh",minHeight:0,display:"flex",flexDirection:"column",background:"var(--surface-page)",color:"var(--text-body)"},children:[r.jsxs("header",{className:"hn-portal-header",style:{...Mr,display:"flex",alignItems:"center",gap:14,padding:"0 22px",height:"var(--topbar-h)",borderBottom:"1px solid var(--border-hair)",background:"var(--bone-100)"},children:[r.jsx("span",{style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:26,height:26,borderRadius:"var(--radius-sm)",background:"var(--accent)"},children:r.jsx(e2,{id:"buntut",size:17,color:"#fff"})}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:18,fontWeight:600,color:"var(--text-strong)"},children:"Portal klien"}),r.jsx("div",{style:{flex:1}}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-subtle)"},children:e.email}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"log-out",onClick:j,children:"Keluar"})]}),r.jsx("main",{"data-testid":"portal-scroll",style:gc,children:r.jsx("div",{className:"hn-portal-content",style:{maxWidth:"var(--content-max)",margin:"0 auto",padding:"24px 28px 32px"},children:a===null?r.jsx(ue,{kind:"loading",title:"Memuat…"}):a.length===0?r.jsx(ue,{kind:A?"error":"empty",icon:"folder",title:A?"Gagal memuat data":"Belum ada project yang bisa dilihat",hint:A?"Coba muat ulang halaman ini.":"Hubungi tim hanoman untuk meminta akses ke project Anda."}):r.jsxs(r.Fragment,{children:[r.jsx("div",{style:{display:"flex",flexWrap:"wrap",gap:8,marginBottom:18},children:a.map(w=>r.jsx(B,{size:"sm",variant:w.id===i?"primary":"ghost",onClick:()=>s(w.id),children:w.name},w.id))}),r.jsxs("div",{className:"hn-portal-toolbar",style:{display:"flex",alignItems:"center",gap:12,marginBottom:14},children:[r.jsx(mi,{value:o,onChange:l,style:{flex:1,minWidth:0},tabs:[{value:"backlog",label:"Pekerjaan",count:c.total},{value:"tickets",label:"Help desk",count:h.total}]}),r.jsx(B,{size:"sm",leftIcon:"send",onClick:()=>P(!0),children:"Kirim keluhan"})]}),o==="backlog"?c.total===0?r.jsx(ue,{kind:"empty",icon:"list-checks",title:"Belum ada pekerjaan tercatat",hint:"Begitu tim mulai mengerjakan sesuatu di project ini, daftarnya muncul di sini."}):r.jsxs(r.Fragment,{children:[r.jsx(be,{padding:0,"data-testid":"portal-list",children:c.items.map(w=>r.jsxs("button",{type:"button",className:"hn-portal-row",onClick:()=>void Gr.getSpec(i,w.id).then(E),style:fb,children:[r.jsx("span",{style:{...Hn,fontFamily:"var(--font-mono)",width:92},children:w.id}),r.jsx("span",{style:{flex:1,minWidth:0,fontWeight:500,color:"var(--text-strong)"},children:w.title}),r.jsx(Oa,{status:mb(w.stage),size:"sm",children:_b[w.stage]??w.stage}),r.jsx("span",{style:Hn,children:w.priority}),r.jsx("span",{style:Hn,children:Ls(w.doneAt??w.startedAt??w.createdAt)})]},w.id))}),r.jsx(gb,{total:c.total,page:p,onPage:g,unit:"pekerjaan"})]}):h.total===0?r.jsx(ue,{kind:"empty",icon:"inbox",title:"Belum ada tiket",hint:"Kirim keluhan lewat tombol Kirim keluhan di atas — atau lewat halaman Help Center project ini."}):r.jsxs(r.Fragment,{children:[r.jsx(be,{padding:0,"data-testid":"portal-list",children:h.items.map(w=>r.jsxs("button",{type:"button",className:"hn-portal-row",onClick:()=>void Gr.getTicket(i,w.id).then(T),style:fb,children:[r.jsxs("span",{style:{...Hn,fontFamily:"var(--font-mono)",width:48},children:["#",w.number]}),r.jsx("span",{style:{flex:1,minWidth:0,fontWeight:500,color:"var(--text-strong)"},children:w.title}),r.jsx("span",{style:Hn,children:w.category}),r.jsx(Oa,{status:pb(w.status),size:"sm",children:w.status}),r.jsx("span",{style:Hn,children:Ls(w.createdAt)})]},w.id))}),r.jsx(gb,{total:h.total,page:_,onPage:S,unit:"tiket"})]})]})})}),x&&a&&a.length>0&&r.jsx(Cse,{projects:a,activeId:i,onCancel:()=>P(!1),onSent:w=>{P(!1),l("tickets"),S(1),w===i?v(O=>O+1):s(w)}}),r.jsx(Tt,{open:!!b,title:(b==null?void 0:b.title)??"",eyebrow:b==null?void 0:b.id,onClose:()=>E(null),children:b&&r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[r.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[r.jsx(Oa,{status:mb(b.stage),size:"sm",children:_b[b.stage]??b.stage}),r.jsxs("span",{style:Hn,children:["prioritas ",b.priority]})]}),r.jsx("p",{style:{margin:0,lineHeight:1.6},children:b.objective}),r.jsxs("dl",{style:Mse,children:[r.jsx("dt",{style:Hn,children:"Dibuat"}),r.jsx("dd",{style:Rp,children:Ls(b.createdAt)}),r.jsx("dt",{style:Hn,children:"Mulai"}),r.jsx("dd",{style:Rp,children:Ls(b.startedAt)}),r.jsx("dt",{style:Hn,children:"Selesai"}),r.jsx("dd",{style:Rp,children:Ls(b.doneAt)})]})]})}),r.jsx(Tt,{open:!!k,title:(k==null?void 0:k.title)??"",eyebrow:k?`#${k.number} · ${k.category}`:void 0,onClose:()=>T(null),children:k&&r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[r.jsx("div",{children:r.jsx(Oa,{status:pb(k.status),size:"sm",children:k.status})}),r.jsx("p",{style:{margin:0,whiteSpace:"pre-wrap",lineHeight:1.6},children:k.detail}),r.jsxs("span",{style:Hn,children:["Dikirim ",Ls(k.createdAt)]})]})})]})}const fb={display:"flex",alignItems:"center",gap:12,width:"100%",padding:"12px 16px",border:"none",borderBottom:"1px solid var(--border-hair)",cursor:"pointer",background:"transparent",color:"inherit",font:"inherit",textAlign:"left"},Hn={fontSize:"var(--text-sm)",color:"var(--text-subtle)"},Mse={display:"grid",gridTemplateColumns:"auto 1fr",gap:"6px 16px",margin:0},Rp={margin:0,fontSize:"var(--text-sm)"};function oA(e,t){return[{value:"",label:e.length?"main (default project)":"project belum punya repo"}].concat(e.map(a=>({value:a,label:t!=null&&t.has(a)?`${a} · origin`:a})))}const Ase=e=>`prd/${e.replace(/^docs\/prd\//,"").replace(/\.md$/,"")}`;function Ose(e){const t=/(?:^|[#&])spec=([^&]+)/.exec(e||"");return t&&t[1]?decodeURIComponent(t[1]):null}function Yf(e,t=window.location){return`${t.origin}${t.pathname}#spec=${encodeURIComponent(e)}`}function Nse(e){const t=/(?:^|[#&])changelog=([^&]+)/.exec(e||"");if(!t||!t[1])return null;const a=/(?:^|[#&])cl=([^&]+)/.exec(e);return{projectId:decodeURIComponent(t[1]),changelogId:a&&a[1]?decodeURIComponent(a[1]):null}}function lA(e,t,a=window.location){const n=t?`&cl=${encodeURIComponent(t)}`:"";return`${a.origin}${a.pathname}#changelog=${encodeURIComponent(e)}${n}`}function Ise(e){return e==="broken"?"err":e==="drift"?"warn":"ok"}function Tl(e){return e.docStatus==="broken"?"high":e.docStatus==="drift"?"low":"none"}const Dse={high:{bar:"var(--clay-500)",tint:"var(--clay-100)",text:"var(--clay-600)",label:"perlu perhatian"},low:{bar:"var(--amber-500)",tint:"var(--amber-100)",text:"var(--amber-600)",label:"docs drift"}};function Lse({items:e}){return r.jsx("div",{className:"hn-stat-grid",style:{display:"grid",gridTemplateColumns:`repeat(${e.length}, 1fr)`,gap:1,background:"var(--border-hair)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflow:"hidden",marginBottom:20},children:e.map(t=>r.jsxs("div",{style:{background:"var(--surface-card)",padding:"16px 18px"},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:7},children:[r.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:t.dot}}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:27,fontWeight:600,color:"var(--text-strong)",lineHeight:1},children:t.value})]}),r.jsx("div",{style:{fontSize:12,color:"var(--text-muted)",marginTop:6},children:t.label}),t.sub&&r.jsx("div",{style:{fontFamily:"var(--font-mono)",fontSize:10.5,color:"var(--text-subtle)",marginTop:3},children:t.sub})]},t.label))})}function Pse({p:e,onOpen:t}){const a=Tl(e),n=Dse[a],i=e.docStatus==="broken"?"Docs off-convention":"Docs drift — sebagian kategori belum ter-index";return r.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:12,padding:"12px 4px",borderBottom:"1px solid var(--border-hair)",borderLeft:`3px solid ${n.bar}`,paddingLeft:12},children:[r.jsxs("div",{style:{minWidth:0,flex:1},children:[r.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",alignItems:"center",gap:8},children:[r.jsx(Ie,{name:"box",size:13,color:"var(--text-muted)"}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:13.5,fontWeight:500,color:"var(--text-strong)"},children:e.name}),r.jsx(Ne,{tone:a==="high"?"err":"warn",size:"sm",children:n.label})]}),r.jsxs("div",{style:{fontSize:12,color:"var(--text-muted)",marginTop:4},children:[i," · ",e.coverage,"% ter-index"]})]}),r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"book-open",onClick:()=>t(e),children:"Buka SoT"})]})}function Bse({p:e,onGoto:t}){return r.jsxs("div",{className:"hn-dense-row",role:"button",tabIndex:0,onClick:()=>t("terminal"),onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),t("terminal"))},style:{display:"flex",alignItems:"center",gap:8,padding:"12px 4px",borderBottom:"1px solid var(--border-hair)",cursor:"pointer"},children:[r.jsx(Oa,{status:"running",size:"sm",children:e.session.phase??"—"}),r.jsx("span",{style:{fontSize:13.5,fontWeight:500,color:"var(--text-strong)",flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.name}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)"},children:e.session.flow??""})]})}function jse({p:e,onOpen:t}){return r.jsxs("div",{className:"hn-grid-mobile",role:"button",tabIndex:0,onClick:()=>t(e),onKeyDown:a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),t(e))},style:{display:"grid",gridTemplateColumns:"92px minmax(0, 1fr) 120px",alignItems:"center",gap:12,padding:"9px 4px",cursor:"pointer",borderBottom:"1px solid var(--border-hair)"},children:[r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12.5,color:"var(--text-strong)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.name}),r.jsx(Oc,{value:e.coverage,tone:Ise(e.docStatus),size:"sm"}),r.jsx(Oa,{status:e.docStatus,size:"sm",style:{justifySelf:"end"}})]})}function kd({icon:e,label:t,value:a,tone:n}){return r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"10px 12px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",background:"var(--bone-100)"},children:[r.jsx("span",{style:{width:30,height:30,borderRadius:"var(--radius-sm)",flex:"0 0 auto",background:"var(--surface-card)",border:"1px solid var(--border-hair)",color:n||"var(--text-muted)",display:"inline-flex",alignItems:"center",justifyContent:"center"},children:r.jsx(Ie,{name:e,size:15})}),r.jsxs("div",{style:{minWidth:0},children:[r.jsx("div",{style:{fontFamily:"var(--font-display)",fontSize:20,fontWeight:600,color:"var(--text-strong)",lineHeight:1},children:a}),r.jsx("div",{style:{fontSize:11.5,color:"var(--text-muted)",marginTop:3},children:t})]})]})}function Fse({projects:e,backlog:t,onOpenProject:a,onGoto:n}){const i=jM(),s=FM(),o=e.filter(b=>b.session.status==="running"),l=e.filter(b=>Tl(b)!=="none").sort((b,E)=>(Tl(b)==="high"?0:1)-(Tl(E)==="high"?0:1)),c=e.filter(b=>b.docStatus==="ok").length,d=e.filter(b=>Tl(b)==="high").length,h=e.length?Math.round(e.reduce((b,E)=>b+E.coverage,0)/e.length):0,m=t.filter(b=>b.source==="brief").length,p=t.filter(b=>b.source==="qa").length,g=t.filter(b=>b.source==="audit").length,_=t.filter(b=>b.priority==="tinggi").length,S=[...e].sort((b,E)=>b.coverage-E.coverage),y=e.map(b=>({project:b.name,status:b.session.status,text:b.activity,commit:b.commit})),v=[{label:"Sesi aktif",value:o.length,dot:"var(--brass-500)"},{label:"Perlu perhatian",value:d,dot:"var(--clay-600)"},{label:"Docs on-convention",value:c+"/"+e.length,sub:"rata-rata "+h+"%",dot:"var(--leaf-600)"},{label:"Spec di backlog",value:t.length,sub:m+" brief · "+p+" QA · "+g+" audit",dot:"var(--wind-600)"}];return r.jsxs("div",{children:[r.jsx(Lse,{items:v}),r.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"1.35fr 1fr",gap:20,alignItems:"start"},children:[r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:20},children:[r.jsx(be,{eyebrow:"needs attention · "+l.length,title:"Perlu perhatian",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"layout-grid",onClick:()=>n("projects"),children:"Semua project"}),children:l.length===0?r.jsx(ue,{kind:"empty",compact:!0,illustration:"PST-005",illustrationDecorative:!0,title:"Semua project on-convention",hint:"Source of Truth utuh — tidak ada yang perlu perhatian."}):r.jsx("div",{style:{marginTop:4},children:l.map(b=>r.jsx(Pse,{p:b,onOpen:a},b.id))})}),r.jsx(be,{eyebrow:"live · "+o.length+" berjalan",title:"Claude Code sedang jalan",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"terminal",onClick:()=>n("terminal"),children:"Buka Terminal"}),children:o.length===0?r.jsx(ue,{kind:"empty",compact:!0,icon:"terminal",title:"Tidak ada sesi aktif",hint:"Mulai sebuah backlog item untuk membuka sesi Claude Code interaktif."}):r.jsx("div",{style:{marginTop:4},children:o.map(b=>r.jsx(Bse,{p:b,onGoto:n},b.id))})})]}),r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:20},children:[r.jsx(be,{eyebrow:"realtime · Claude",title:"Limit langganan",children:r.jsx(qu,{dto:i})}),s.status!=="unavailable"&&r.jsx(be,{eyebrow:`snapshot · Codex${s.plan?` · ${s.plan}`:""}`,title:"Limit langganan",children:r.jsx(qu,{dto:s})}),r.jsx(be,{eyebrow:"Source of Truth",title:"Docs coverage",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"book-open",onClick:()=>n("docs"),children:"Docs"}),children:S.length===0?r.jsx(ue,{kind:"empty",compact:!0,icon:"book-open",title:"Belum ada project",hint:"Coverage Source of Truth muncul setelah project pertama ditambahkan."}):r.jsx("div",{style:{marginTop:4},children:S.map(b=>r.jsx(jse,{p:b,onOpen:a},b.id))})}),r.jsx(be,{eyebrow:"brainstorm → execute",title:"Backlog",actions:r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"list-checks",onClick:()=>n("backlog"),children:"Buka"}),children:r.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10,marginTop:6},children:[r.jsx(kd,{icon:"lightbulb",label:"dari brief",value:m,tone:"var(--brass-600)"}),r.jsx(kd,{icon:"bug",label:"dari QA",value:p,tone:"var(--clay-500)"}),r.jsx(kd,{icon:"flame",label:"prioritas tinggi",value:_,tone:"var(--clay-500)"}),r.jsx(kd,{icon:"layers",label:"total spec",value:t.length,tone:"var(--wind-600)"})]})})]})]}),r.jsx("div",{style:{marginTop:20},children:r.jsx(be,{eyebrow:"workspace",title:"Aktivitas terbaru",children:y.length===0?r.jsx(ue,{kind:"empty",compact:!0,icon:"history",title:"Belum ada aktivitas",hint:"Sesi dan branch terakhir tiap project akan tampil di sini."}):r.jsx("div",{style:{marginTop:4},children:y.map((b,E)=>{const k=b.status==="running"?"var(--brass-500)":"var(--bone-400)";return r.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:12,padding:"9px 4px",borderBottom:"1px solid var(--border-hair)"},children:[r.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:k,flex:"0 0 auto"}}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12.5,color:"var(--text-strong)",width:120,flex:"0 0 auto",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:b.project}),r.jsx("span",{style:{fontSize:12.5,color:"var(--text-body)",flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:b.text}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",maxWidth:160},children:b.commit})]},E)})})})})]})}function Use(e){return e==="broken"?"err":e==="drift"?"warn":"ok"}function cA(e){return e.docStatus==="broken"?"high":e.docStatus==="drift"?"low":"none"}const zse={high:{bar:"var(--clay-500)",tint:"var(--clay-100)",text:"var(--clay-600)"},low:{bar:"var(--amber-500)",tint:"var(--amber-100)",text:"var(--amber-600)"}};function Hse({projects:e}){const t=e.filter(o=>o.session.status==="running").length,a=e.reduce((o,l)=>o+l.backlog,0),n=e.filter(o=>o.docStatus==="ok").length,i=e.filter(o=>cA(o)==="high").length,s=[{label:"Run aktif",value:t,dot:"var(--brass-500)"},{label:"Total di backlog",value:a,dot:"var(--wind-600)"},{label:"On convention",value:n+"/"+e.length,dot:"var(--leaf-600)"},{label:"Perlu perhatian",value:i,dot:"var(--clay-600)"}];return r.jsx("div",{className:"hn-stat-grid",style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:1,background:"var(--border-hair)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflow:"hidden",marginBottom:20},children:s.map(o=>r.jsxs("div",{style:{background:"var(--surface-card)",padding:"15px 18px"},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:7},children:[r.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:o.dot}}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:27,fontWeight:600,color:"var(--text-strong)",lineHeight:1},children:o.value})]}),r.jsx("div",{style:{fontSize:12,color:"var(--text-muted)",marginTop:6},children:o.label})]},o.label))})}function Gse({p:e,onOpen:t,onDelete:a}){const n=cA(e),i=e.session.status==="running",[s,o]=f.useState(!1);return r.jsxs("div",{className:"hn-project-row",onClick:t?()=>t(e):void 0,onMouseEnter:()=>o(!0),onMouseLeave:()=>o(!1),style:{display:"grid",gridTemplateColumns:"1.7fr 1.2fr 1.5fr 1.1fr 1.4fr",alignItems:"center",gap:12,padding:"11px 14px 11px 12px",borderBottom:"1px solid var(--border-hair)",borderLeft:`3px solid ${n==="none"?"transparent":zse[n].bar}`,cursor:t?"pointer":"default",background:s&&t?"var(--bone-100)":"transparent",transition:"background 120ms ease"},children:[r.jsx("div",{"data-label":"Project",style:{minWidth:0},children:r.jsxs("button",{type:"button",className:"hn-project-open","aria-label":`Buka project ${e.name}`,disabled:!t,onClick:l=>{l.stopPropagation(),t==null||t(e)},style:{all:"unset",display:"block",width:"100%",cursor:t?"pointer":"default"},children:[r.jsxs("span",{style:{display:"flex",alignItems:"center",gap:7},children:[r.jsx(Ie,{name:"box",size:13,color:"var(--text-muted)"}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:13.5,fontWeight:500,color:"var(--text-strong)"},children:e.name}),r.jsx(Ne,{tone:e.kind==="from-scratch"?"brass":"neutral",size:"sm",children:e.kind})]}),r.jsx("span",{style:{display:"block",fontSize:11.5,color:"var(--text-subtle)",marginTop:3,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.desc})]})}),r.jsx("div",{"data-label":"Status",children:r.jsx(Oa,{status:e.session.status,size:"sm",children:i&&e.session.phase?e.session.phase:void 0})}),r.jsx("div",{"data-label":"Docs · SoT",style:{paddingRight:8},children:r.jsx(Oc,{value:e.coverage,showLabel:!0,tone:Use(e.docStatus),size:"sm"})}),r.jsxs("div",{"data-label":"Backlog",style:{fontFamily:"var(--font-mono)",fontSize:11.5,color:"var(--text-muted)"},children:[e.backlog," · ",e.topStage]}),r.jsxs("div",{"data-label":"Aktivitas",style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"flex",alignItems:"center",gap:6,justifyContent:"space-between"},children:[r.jsx("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.activity}),a&&r.jsx("span",{onClick:l=>{l.stopPropagation(),a(e)},children:r.jsx(Gu,{size:"sm",variant:"ghost",icon:"trash-2",label:"Hapus project "+e.name})}),t&&r.jsx(Ie,{name:"chevron-right",size:14,color:"var(--text-subtle)"})]})]})}function qse({projects:e,onOpen:t,onDelete:a,pageSize:n,search:i="",dataVersion:s,onClearSearch:o}){const l=["Project","Status","Docs · SoT","Backlog","Aktivitas"],c="1.7fr 1.2fr 1.5fr 1.1fr 1.4fr",[d,h]=f.useState(e),[m,p]=f.useState(e.length),[g,_]=rt("projects","page",1,Hi),S=wh("projects","scroll",d.length>0);f.useEffect(()=>{_(1)},[i]),f.useEffect(()=>{var E;if(!n){h(e),p(e.length);return}let v=!0;const b=(E=F.listProjects)==null?void 0:E.call(F,{q:i||void 0,page:g,limit:n});return b==null||b.then(k=>{v&&(h(k.items),p(k.total))}).catch(()=>{}),()=>{v=!1}},[i,g,n,s,e]);const y=gi(m,g,n||m||1);return r.jsxs("div",{style:J0,children:[r.jsx("div",{style:Mr,children:r.jsx(Hse,{projects:e})}),d.length===0&&i?r.jsx(ue,{kind:"empty",icon:"search",title:`Tidak ada project cocok dengan “${i}”`,hint:"Coba kata kunci lain, atau kosongkan pencarian.",action:o,actionLabel:"Hapus pencarian",actionIcon:"x"}):r.jsxs(be,{padding:0,fill:!0,children:[r.jsx("div",{className:"hn-project-header",style:{...Mr,display:"grid",gridTemplateColumns:c,gap:12,padding:"10px 14px 10px 15px",borderBottom:"1px solid var(--border-hair)"},children:l.map(v=>r.jsx("span",{className:"hn-eyebrow",children:v},v))}),r.jsx("div",{ref:S,"data-testid":"projects-scroll",style:gc,children:d.map(v=>r.jsx(Gse,{p:v,onOpen:t,onDelete:a},v.id))}),n&&r.jsx(fi,{page:y.page,pageCount:y.pageCount,total:m,from:y.from,to:y.to,onPage:_,unit:"project"})]})]})}const $se=()=>({name:"",description:"",instructions:"",tools:[],model:"",mentions:[],runtime:"",enabled:!0}),Vse=e=>({name:e.name,description:e.description,instructions:e.instructions,tools:e.tools??[],model:e.model??"",mentions:e.mentions,runtime:e.runtime??"",enabled:e.enabled});function xd(e){if(!(e instanceof Mt))return(e==null?void 0:e.message)??"gagal";const t=e.detail??{};return Array.isArray(t.cycle)&&t.cycle.length?`Mention membentuk siklus di scope ${t.scope??"?"}: ${t.cycle.join(" → ")}`:Array.isArray(t.unknown)&&t.unknown.length?`Mention tak dikenal: ${t.unknown.join(", ")}`:Array.isArray(t.unknownTools)&&t.unknownTools.length?`Tool tak dikenal di mesin ini: ${t.unknownTools.join(", ")}`:typeof t.model=="string"?`Model "${t.model}" tak tersedia untuk runtime ${t.runtime??"warisi"}.`:typeof t.error=="string"?t.error:`Gagal (${e.status})`}function dA({projectId:e,onToast:t}){const[a,n]=f.useState(null),[i,s]=f.useState(null),[o,l]=f.useState(""),[c,d]=f.useState(null),[h,m]=f.useState(!1),p=f.useCallback(async()=>{try{n(await F.listCustomAgents(e??void 0))}catch(w){l(xd(w)),n([])}try{s(await F.getCustomAgentCatalog(e??void 0))}catch{s({tools:[],models:[],runtimes:[]})}},[e]);f.useEffect(()=>{p()},[p]);const g=(a??[]).filter(w=>w.name!==(c==null?void 0:c.draft.name)),_=!(c!=null&&c.draft.name)||V0.test(c.draft.name),S=(c==null?void 0:c.draft.runtime)||null,y=((i==null?void 0:i.tools)??[]).map(w=>w.id),v=((i==null?void 0:i.tools)??[]).map(w=>({value:w.id,label:w.label,...w.group==="mcp"?{group:"MCP"}:{}})),b=bv(S).filter(w=>!i||i.models.length===0||i.models.some(O=>O.id===w.id)).map(w=>({value:w.id,label:S?w.label:`${w.label} · ${w.runtime}`})),E=g.map(w=>({value:w.name,label:w.name})),k=((c==null?void 0:c.draft.tools)??[]).filter(w=>!y.includes(w)),T=((c==null?void 0:c.draft.mentions)??[]).filter(w=>!E.some(O=>O.value===w)),A=!!(c!=null&&c.draft.model)&&!b.some(w=>w.value===c.draft.model),M=k.length>0||T.length>0||A,x=w=>{if(!c)return;const H=w.includes(Os)&&!c.draft.tools.includes(Os)?[Os]:w.filter(N=>N!==Os);d({...c,draft:{...c.draft,tools:H}})},P=w=>{if(!c)return;const H=bv(w||null).map(N=>N.id).includes(c.draft.model)?c.draft.model:"";d({...c,draft:{...c.draft,runtime:w,model:H}})};async function R(){if(!c)return;const w=c.draft;m(!0),l("");try{const O={description:w.description,instructions:w.instructions,tools:w.tools.length?w.tools:null,model:w.model||null,mentions:w.mentions,runtime:w.runtime||null,enabled:w.enabled};c.id?await F.updateCustomAgent(c.id,O):await F.createCustomAgent({...O,name:w.name,projectId:e}),d(null),await p(),t==null||t(c.id?"Agen diperbarui":"Agen dibuat","ok")}catch(O){l(xd(O))}finally{m(!1)}}async function G(w,O){l("");try{await F.updateCustomAgent(w.id,{enabled:O}),await p()}catch(H){l(xd(H))}}async function j(w){l("");try{await F.deleteCustomAgent(w.id),await p(),t==null||t("Agen dihapus","ok")}catch(O){l(xd(O))}}return a===null?r.jsx(ue,{kind:"loading",title:"Memuat custom agent…"}):r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10},children:[r.jsx("div",{style:{flex:1,minWidth:0,fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:e?"Agen project ini, ditambah agen global yang berlaku di sini. Agen project menimpa agen global bernama sama.":"Agen global — tersedia di semua project. Satu project bisa menimpanya dengan agen bernama sama."}),r.jsx(B,{size:"sm",onClick:()=>{l(""),d({id:null,draft:$se()})},children:"Agen baru"})]}),o&&r.jsx(Nn,{tone:"err",children:o}),a.length===0&&!c&&r.jsx(ue,{kind:"empty",compact:!0,title:"Belum ada custom agent",hint:"Custom agent adalah persona yang bisa dipilih sesi claude & codex — misalnya peninjau keamanan atau penulis migration."}),a.map(w=>{const O=(w.tools??[]).includes(Os)?((i==null?void 0:i.tools)??[]).map(z=>z.id).filter(z=>z!==Os):w.tools,H=gD({tools:O,mentions:w.mentions}),N=!!(e&&w.inherited);return r.jsxs(be,{padding:14,children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:6},children:[r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:w.name}),N&&r.jsx(Ne,{tone:"neutral",size:"sm",children:"warisan global"}),!w.enabled&&r.jsx(Ne,{tone:"warn",size:"sm",children:"nonaktif"}),w.runtime&&r.jsx(Ne,{tone:"neutral",size:"sm","data-testid":`runtime-${w.name}`,children:w.runtime}),r.jsx("span",{style:{flex:1}}),r.jsx(ta,{checked:w.enabled,disabled:N,"aria-label":`Aktifkan ${w.name}`,onChange:z=>void G(w,z)}),r.jsx(B,{size:"sm",variant:"ghost",disabled:N,onClick:()=>{l(""),d({id:w.id,draft:Vse(w)})},children:"Ubah"}),r.jsx(B,{size:"sm",variant:"ghost",disabled:N,onClick:()=>void j(w),children:"Hapus"})]}),r.jsx("div",{style:{fontSize:"var(--text-xs)",color:"var(--text-muted)",marginBottom:6},children:w.description}),r.jsxs("div",{style:{display:"flex",gap:16,flexWrap:"wrap",fontSize:"var(--text-xs)",color:"var(--text-subtle)"},children:[r.jsxs("span",{"data-testid":`tools-${w.name}`,children:["Tools: ",H.join(", ")]}),r.jsxs("span",{"data-testid":`mentions-${w.name}`,children:["Mention: ",w.mentions.length?w.mentions.map(z=>`@${z}`).join(", "):"—"]}),w.model&&r.jsxs("span",{children:["Model: ",w.model]})]})]},w.id)}),c&&r.jsxs(be,{padding:16,children:[r.jsx(fe,{label:"Nama",hint:c.id?"Nama tak bisa diubah — hapus lalu buat baru (definisi ini menyeberang lewat sync).":"huruf kecil, angka, dan tanda hubung; minimal 2 karakter",children:r.jsx(je,{value:c.draft.name,"aria-label":"Nama",disabled:!!c.id,invalid:!_,placeholder:"mis. peninjau-keamanan",onChange:w=>d({...c,draft:{...c.draft,name:w.target.value}})})}),r.jsx(fe,{label:"Deskripsi",hint:"Kapan agen ini dipakai — inilah yang dibaca agen untuk MEMILIH.",children:r.jsx(je,{value:c.draft.description,"aria-label":"Deskripsi",placeholder:"mis. Dipakai saat meninjau perubahan yang menyentuh auth",onChange:w=>d({...c,draft:{...c.draft,description:w.target.value}})})}),r.jsx(fe,{label:"Instruksi",hint:"System prompt agen.",children:r.jsx(Ta,{value:c.draft.instructions,"aria-label":"Instruksi",rows:6,placeholder:"mis. Kamu peninjau keamanan. Baca diff, laporkan temuan berurut dari yang paling berbahaya, sebut file:line.",onChange:w=>d({...c,draft:{...c.draft,instructions:w.target.value}})})}),r.jsx(fe,{label:"Tools",hint:`Kosongkan untuk memakai default: ${hM.join(", ")}. Alat delegasi (Task) diatur otomatis dari Mention.`,children:r.jsx(Uv,{"aria-label":"Tools",options:v,value:c.draft.tools,invalidValues:k,onChange:x,placeholder:"Pilih tools…",searchPlaceholder:"mis. Read atau Bash"})}),r.jsx(fe,{label:"Runtime agent",hint:"Mesin sesi yang memakai agen ini. Kosongkan untuk ikut sesi induk — dipakai sesi claude maupun codex.",children:r.jsx(xe,{"aria-label":"Runtime agent",value:c.draft.runtime,options:[{value:"",label:"Ikut sesi induk"},...((i==null?void 0:i.runtimes)??[]).map(w=>({value:w.id,label:w.label}))],onChange:w=>P(w.target.value)})}),r.jsx(fe,{label:"Model",hint:"Kosongkan untuk mewarisi model sesi.",children:r.jsx(xe,{"aria-label":"Model",value:c.draft.model,invalid:A,options:[{value:"",label:"Ikut sesi induk"},...b,...A?[{value:c.draft.model,label:`⚠ ${c.draft.model} — tak ada di katalog`}]:[]],onChange:w=>d({...c,draft:{...c.draft,model:w.target.value}})})}),r.jsx(fe,{label:"Mention",hint:"Agen yang boleh dipanggil agen ini. Graf mention wajib asiklik — server menolak yang membentuk lingkaran.",children:r.jsx(Uv,{"aria-label":"Mention",options:E,value:c.draft.mentions,invalidValues:T,onChange:w=>d({...c,draft:{...c.draft,mentions:w}}),placeholder:"Pilih agen…",searchPlaceholder:"mis. peninjau-keamanan",emptyText:"Belum ada agen lain."})}),M&&r.jsx(Nn,{tone:"warn",children:"Ada nilai yang tak ada di katalog mesin ini (ditandai ⚠). Buang dulu sebelum menyimpan — server menolak nilai yang tak dikenal."}),r.jsxs("div",{style:{display:"flex",gap:8},children:[r.jsx(B,{onClick:()=>void R(),loading:h,disabled:!_||M,children:"Simpan"}),r.jsx(B,{variant:"ghost",onClick:()=>{d(null),l("")},children:"Batal"})]})]})]})}const Yse=[{value:"off",label:"Tanpa auto-merge (default)"},{value:"default-branch",label:"Auto-merge ke default branch repo"},{value:"branch",label:"Auto-merge ke branch tujuan…"}],Wse=[{value:"local",label:"Branch lokal (perbarui ref di checkout ini)"},{value:"origin",label:"Origin (push ke remote)"}];function Kse({p:e,onToast:t,onProjectChanged:a}){const n=e.autoMerge??null,[i,s]=f.useState(n??po),[o,l]=f.useState({local:[],origin:[],def:null}),[c,d]=f.useState(!1),h=e.binding??e.repoDir??null;f.useEffect(()=>{s(n??po)},[n]),f.useEffect(()=>{let _=!0;return F.listBranches(e.id).then(S=>{_&&l({local:S.branches,origin:S.remotes,def:S.defaultBranch??null})}).catch(()=>{_&&l({local:[],origin:[],def:null})}),()=>{_=!1}},[e.id]);const m=o[i.dest==="origin"?"origin":"local"],p=_=>S=>s(y=>({...y,[_]:S}));async function g(){d(!0);try{await F.updateProject(e.id,{autoMerge:i.mode==="off"?null:i}),t("Kebijakan auto-merge disimpan","ok","git-merge"),await(a==null?void 0:a(e.id))}catch(_){t(`Gagal menyimpan: ${_.message}`,"err","x-circle")}finally{d(!1)}}return r.jsxs(be,{eyebrow:"integrasi",title:"Auto-merge saat sesi selesai",actions:r.jsx(B,{size:"sm",leftIcon:"check",disabled:c||!h,onClick:g,children:"Simpan"}),children:[r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Saat sebuah backlog item mencapai ",r.jsx("b",{children:"Selesai"}),", hanoman menggabungkan branch kerjanya (",r.jsx("code",{children:"hanoman/<spec>"}),") ke branch tujuan. Merge saja — tak pernah rebase, tak pernah force-push. Konflik tidak menghapus apa pun: branch kerja tetap utuh dan kamu dapat notifikasi berisi alasannya. Item bisa menimpa setelan ini satu per satu dari Backlog."]}),!h&&r.jsxs("div",{style:{fontSize:12.5,color:"var(--status-warn, var(--text-muted))",marginBottom:12},children:["Project ini belum di-bind ke checkout lokal — atur ",r.jsx("b",{children:"repoDir"})," dulu (Edit project) sebelum menyalakan auto-merge."]}),r.jsx("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:12,flexWrap:"wrap"},children:r.jsx(Ne,{tone:n&&n.mode!=="off"?"ok":"neutral",size:"sm",children:iM(n??po)})}),r.jsxs("div",{style:{display:"grid",gap:10},children:[r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Mode"}),r.jsx(xe,{size:"sm","aria-label":"Mode auto-merge",value:i.mode,disabled:!h,onChange:_=>p("mode")(_.target.value),options:Yse})]}),i.mode!=="off"&&r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Tujuan"}),r.jsx(xe,{size:"sm","aria-label":"Tujuan",value:i.dest,disabled:!h,onChange:_=>p("dest")(_.target.value),options:Wse})]}),i.mode==="default-branch"&&r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-subtle)"},children:["Default branch repo saat ini: ",r.jsx("b",{children:o.def??"— tak terbaca"}),". Diresolve ulang tiap kali auto-merge berjalan, jadi mengganti default branch repo tak menyisakan setelan basi."]}),i.mode==="branch"&&r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Branch tujuan"}),r.jsx(xe,{size:"sm","aria-label":"Branch tujuan",value:i.branch??"",disabled:!h||!m.length,onChange:_=>p("branch")(_.target.value||null),options:[{value:"",label:"Pilih branch…"},...m.map(_=>({value:_,label:_}))]})]}),i.mode!=="off"&&r.jsx(gn,{"aria-label":"Hapus branch kerja setelah merge sukses",checked:i.deleteBranch,label:"Hapus branch kerja setelah merge sukses",onChange:()=>p("deleteBranch")(!i.deleteBranch)})]})]})}const Qse=e=>e==="broken"?"err":e==="drift"?"warn":"ok";function Zse({p:e,onToast:t,onProjectChanged:a}){const[n,i]=f.useState(e.helpEnabled),[s,o]=f.useState(!1),l=`${window.location.origin}/help/${encodeURIComponent(e.id)}`;async function c(){o(!0);try{await F.enableHelpCenter(e.id),i(!0),t("Help Center aktif","ok","inbox"),await(a==null?void 0:a(e.id))}catch{t("Gagal mengaktifkan Help Center","err","x-circle")}finally{o(!1)}}async function d(){if(window.confirm(`Nonaktifkan Help Center project "${e.name}"? Link publik berhenti menerima keluhan baru (tiket lama tetap ada).`)){o(!0);try{await F.disableHelpCenter(e.id),i(!1),t("Help Center nonaktif","ok","inbox"),await(a==null?void 0:a(e.id))}catch{t("Gagal menonaktifkan Help Center","err","x-circle")}finally{o(!1)}}}return r.jsxs(be,{eyebrow:"help center",title:"Link publik keluhan",actions:n?r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"ban",onClick:d,disabled:s,children:"Nonaktifkan"}):r.jsx(B,{size:"sm",leftIcon:"inbox",onClick:c,disabled:s,children:"Aktifkan"}),children:[r.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:10,lineHeight:1.5},children:"Saat aktif, sebar link ini agar pengguna project melapor keluhan tanpa login. Keluhan masuk ke antrean Triase."}),r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[r.jsx(Ne,{tone:n?"ok":"neutral",size:"sm",children:n?"aktif":"nonaktif"}),n&&l&&r.jsxs(r.Fragment,{children:[r.jsx("code",{style:{fontFamily:"var(--font-mono)",fontSize:12.5,color:"var(--text-body)",wordBreak:"break-all"},children:l}),r.jsx(B,{size:"sm",leftIcon:"copy",onClick:()=>{var h;(h=navigator.clipboard)==null||h.writeText(l),t("Link disalin","ok","copy")},children:"Salin"})]})]})]})}function ol({label:e,value:t,mono:a}){return r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",children:e}),r.jsx("div",{style:{marginTop:4,fontSize:12.5,color:"var(--text-body)",fontFamily:a?"var(--font-mono)":"var(--font-ui)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:t})]})}function Ps({icon:e,title:t,hint:a,onClick:n}){return r.jsx(be,{padding:0,children:r.jsxs("button",{type:"button",onClick:n,style:{display:"flex",alignItems:"center",gap:12,width:"100%",padding:"14px 16px",cursor:"pointer",textAlign:"left",border:"none",background:"transparent",color:"inherit"},children:[r.jsx(Ie,{name:e,size:16,color:"var(--text-muted)"}),r.jsxs("div",{style:{flex:1,minWidth:0},children:[r.jsx("div",{style:{fontSize:13.5,fontWeight:500,color:"var(--text-strong)"},children:t}),r.jsx("div",{style:{fontSize:11.5,color:"var(--text-subtle)",marginTop:2},children:a})]}),r.jsx(Ie,{name:"chevron-right",size:14,color:"var(--text-subtle)"})]})})}function Xse({p:e,onEdit:t,onGotoDocs:a,onGotoTerminal:n,onGotoBacklog:i,onGotoChangelog:s,onDelete:o,onReverse:l,onScaffold:c,onToast:d,onProjectChanged:h}){return r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:20},children:[r.jsxs(be,{children:[r.jsxs("div",{className:"hn-stack-mobile",style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:16},children:[r.jsxs("div",{style:{minWidth:0},children:[r.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",alignItems:"center",gap:8},children:[r.jsx(Ie,{name:"box",size:15,color:"var(--text-muted)"}),r.jsx("span",{style:{fontFamily:"var(--font-display)",fontSize:22,fontWeight:600,color:"var(--text-strong)"},children:e.name}),r.jsx(Ne,{tone:e.kind==="from-scratch"?"brass":"neutral",size:"sm",children:e.kind}),r.jsx(Oa,{status:e.session.status,size:"sm",children:e.session.phase??void 0})]}),r.jsx("div",{style:{fontSize:12.5,color:"var(--text-subtle)",marginTop:6},children:e.desc})]}),r.jsxs("div",{className:"hn-row-actions",style:{display:"flex",gap:8,flex:"0 0 auto"},children:[r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"pencil",onClick:t,children:"Edit project"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"trash-2",onClick:o,children:"Hapus project"})]})]}),r.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"repeat(4, 1fr)",gap:16,marginTop:20},children:[r.jsx(ol,{label:"ID",value:e.id,mono:!0}),r.jsx(ol,{label:e.binding?"Repo · mesin ini":"Repo",value:(e.binding??e.repoDir)||"—",mono:!0}),r.jsx(ol,{label:"Git remote",value:e.gitRemote||"—",mono:!0}),r.jsx(ol,{label:"Stack",value:e.stack||"—"}),r.jsx(ol,{label:"Backlog terbuka",value:`${e.backlog} · ${e.topStage}`})]}),r.jsxs("div",{style:{marginTop:18},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Docs · SoT"}),r.jsx(Oc,{value:e.coverage,showLabel:!0,tone:Qse(e.docStatus),size:"sm"})]})]}),r.jsx(Zse,{p:e,onToast:d,onProjectChanged:h}),r.jsx(Kse,{p:e,onToast:d,onProjectChanged:h}),r.jsxs(be,{eyebrow:"agen",title:"Custom agent — project ini",children:[r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Persona khusus project ini, ditambah agen global yang berlaku di sini. Agen project",r.jsx("b",{children:" menimpa"})," agen global bernama sama — termasuk untuk mematikannya di project ini saja."]}),r.jsx(dA,{projectId:e.id,onToast:d})]}),r.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(190px, 1fr))",gap:12},children:[r.jsx(Ps,{icon:"book-open",title:"Source of Truth",hint:"baca & sunting docs",onClick:a}),r.jsx(Ps,{icon:"terminal",title:"Buka terminal",hint:"sesi claude project ini",onClick:n}),r.jsx(Ps,{icon:"list-checks",title:"Lihat backlog",hint:`${e.backlog} spec terbuka`,onClick:i}),r.jsx(Ps,{icon:"megaphone",title:"Changelog",hint:"ringkasan rilis untuk pemakai",onClick:s}),l&&r.jsx(Ps,{icon:"radar",title:"Reverse docs",hint:"susun Source of Truth dari kode",onClick:l}),c&&r.jsx(Ps,{icon:"sparkles",title:"Scaffold docs",hint:"susun Source of Truth dari ide",onClick:c})]})]})}const Jse={audit:"Audit",spec:"Spec",plan:"Plan",objective:"Objective",brainstorm:"Brainstorm",other:"Lainnya"};function uA({specId:e,onClose:t}){const[a,n]=f.useState(null),[i,s]=f.useState(!1),[o,l]=f.useState(""),[c,d]=f.useState("files"),[h,m]=f.useState({});f.useEffect(()=>{let y=!0;return n(null),s(!1),l(""),m({}),d("files"),F.getSpecDocs(e).then(v=>{y&&(n(v.files),v.files[0]&&l(v.files[0].path))}).catch(()=>{y&&s(!0)}),()=>{y=!1}},[e]),f.useEffect(()=>{if(!o||o in h)return;let y=!0;return F.getSpecDocFile(e,o).then(v=>{y&&m(b=>({...b,[o]:v.content}))}).catch(()=>{y&&m(v=>({...v,[o]:null}))}),()=>{y=!1}},[o,e,h]);const p=a===null&&!i,g=!!o&&!(o in h),_=o?h[o]===null:!1,S=[];for(const y of a??[]){const v=S[S.length-1];v&&v.kind===y.kind?v.items.push(y):S.push({kind:y.kind,items:[y]})}return r.jsx(Tt,{open:!0,title:"Dokumen backlog item",eyebrow:e,icon:"file-text",onClose:t,width:900,fillHeight:!0,children:i?r.jsx(ue,{kind:"error",title:"Gagal memuat daftar dokumen",hint:e}):p?r.jsx(ue,{kind:"loading",title:"Memuat dokumen…",hint:e}):a.length?r.jsx(No,{ariaLabel:"Panel dokumen backlog",active:c,onActiveChange:y=>d(y),masterWidth:240,className:"hn-workspace-panels",style:{height:"100%"},panels:[{id:"files",label:"Files",className:"hn-panel-flex",content:r.jsx("div",{style:{overflow:"auto",borderRight:"1px solid var(--border-hair)",paddingRight:8},children:S.map(y=>r.jsxs("div",{style:{marginBottom:10},children:[r.jsx("div",{className:"hn-eyebrow",style:{padding:"4px 6px",color:"var(--text-subtle)"},children:Jse[y.kind]??y.kind}),y.items.map(v=>{const b=v.path===o;return r.jsxs("button",{onClick:()=>{l(v.path),d("preview")},style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"6px 8px",borderRadius:"var(--radius-sm)",border:"none",cursor:"pointer",textAlign:"left",background:b?"var(--brass-100)":"transparent"},children:[r.jsx(Ie,{name:"file-text",size:13,color:b?"var(--brass-700)":"var(--text-subtle)"}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11.5,color:b?"var(--brass-700)":"var(--text-body)",fontWeight:b?600:400,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:v.name})]},v.path)})]},y.kind))})},{id:"preview",label:"Preview",className:"hn-panel-flex",content:r.jsxs("div",{style:{display:"flex",flexDirection:"column",minHeight:0},children:[r.jsx("div",{style:{display:"flex",justifyContent:"flex-end",paddingBottom:6,borderBottom:"1px solid var(--border-hair)",marginBottom:8},children:r.jsx(Do,{href:y=>F.specDocDownloadUrl(e,o,y),disabled:!o||g||_})}),r.jsx("div",{"data-testid":"doc-preview-scroll",style:{flex:"1 1 auto",minHeight:0,overflow:"auto",padding:"0 8px 16px"},children:g?r.jsx(ue,{kind:"loading",title:"Memuat…",hint:o}):_?r.jsx(ue,{kind:"error",title:"Gagal memuat berkas",hint:o}):r.jsx(Ar,{text:h[o]??"",name:o})})]})}]}):r.jsx(ue,{kind:"empty",icon:"file-text",title:"Belum ada dokumen untuk item ini",hint:"Jalankan item ini agar agent menulis audit/spec/plan."})})}function Wf({projectId:e,ownBranch:t,eyebrow:a,onClose:n,onIntegrate:i}){const[s,o]=f.useState({local:[],origin:[]}),[l,c]=f.useState(""),d=t;f.useEffect(()=>{let p=!0;return F.listBranches(e).then(g=>{p&&o({local:g.branches.filter(_=>_!==d),origin:g.remotes.filter(_=>_!==d)})}).catch(()=>{p&&o({local:[],origin:[]})}),()=>{p=!1}},[e,d]);const h=[{value:"",label:"Pilih target…"},...s.local.map(p=>({value:`local:${p}`,label:`${p} (lokal)`})),...s.origin.map(p=>({value:`origin:${p}`,label:`origin/${p}`}))],m=p=>{l&&i(p,l)};return r.jsxs(Tt,{open:!0,title:"Rebase / Merge",eyebrow:`${a} · ${d}`,icon:"git-merge",onClose:n,children:[r.jsxs("div",{style:{fontSize:13,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Rebase menata ulang branch di atas target (force-push balik ke branch itu). Merge menggabungkan branch ke target. Bila ada konflik, sesi agen membereskannya di Terminal — agen, model & effort-nya diatur di ",r.jsx("b",{children:"Settings → Model sesi → Konflik rebase & merge"})," ","(SPEC-383/ADR-0081); selama kartu itu mati, ia mengikuti default global."]}),r.jsxs("div",{style:{marginBottom:16},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Target"}),r.jsx(xe,{size:"sm","aria-label":"Target",value:l,disabled:h.length===1,onChange:p=>c(p.target.value),options:h})]}),r.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end"},children:[r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"git-branch",disabled:!l,onClick:()=>m("rebase"),children:"Rebase"}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"git-merge",disabled:!l,onClick:()=>m("merge"),children:"Merge"})]})]})}function eoe(e){return new Date(e.localUpdatedAt)>=new Date(e.serverUpdatedAt)?"local":"server"}function toe(e){try{return JSON.stringify(e,null,2)}catch{return String(e)}}function aoe({open:e,onClose:t,onResolved:a}){const[n,i]=f.useState([]),[s,o]=f.useState(null),[l,c]=f.useState(null),d=f.useCallback(async()=>{try{i((await F.listConflicts()).conflicts)}catch{i([])}},[]);f.useEffect(()=>{e&&d()},[e,d]);const h={"still-conflict":"Hub bergeser lagi sebelum keputusan ini masuk. Coba lagi — datanya sudah disegarkan.","not-found":"Konflik ini sudah tak ada di hub (mungkin sudah diselesaikan dari mesin lain)."};async function m(p,g){const _=`${p.entity}:${p.recordId}`;o(_),c(null);try{const S=await F.resolveConflict(p.entity,p.recordId,g);S.ok||c(h[S.reason??""]??`Gagal menyimpan keputusan (${S.reason??"tak diketahui"}).`),await d(),S.ok&&a()}catch(S){c(`Gagal menghubungi server: ${S.message}`)}finally{o(null)}}return r.jsxs(Tt,{open:e,title:"Rekonsil konflik sync",eyebrow:"SPEC-270",icon:"git-merge",width:720,onClose:t,children:[l&&r.jsx("div",{"data-testid":"resolve-error",role:"alert",style:{fontSize:12.5,color:"var(--danger, #b23b3b)",border:"1px solid var(--danger, #b23b3b)",borderRadius:6,padding:"8px 10px",marginBottom:12},children:l}),n.length===0&&r.jsx("div",{style:{fontSize:13.5,color:"var(--text-muted)"},children:"Tak ada konflik. Semua sinkron."}),n.map(p=>{const g=eoe(p),_=`${p.entity}:${p.recordId}`;return r.jsxs("div",{style:{border:"1px solid var(--line)",borderRadius:8,padding:12,marginBottom:12},children:[r.jsxs("div",{style:{fontSize:12,color:"var(--text-muted)",marginBottom:6},children:[p.entity," · ",p.recordId," · ",r.jsxs("span",{"data-testid":"default-side",children:["default: ",g==="local"?"Lokal":"Server"," (updatedAt terbaru)"]})]}),r.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:10},children:[r.jsx(yb,{label:"Lokal",data:p.localData,at:p.localUpdatedAt,ver:p.localVersion,active:g==="local"}),r.jsx(yb,{label:"Server",data:p.serverData,at:p.serverUpdatedAt,ver:p.serverVersion,active:g==="server"})]}),r.jsxs("div",{style:{display:"flex",gap:8,marginTop:10,justifyContent:"flex-end"},children:[r.jsx(B,{size:"sm",variant:g==="local"?"primary":"secondary",disabled:s===_,onClick:()=>m(p,"local"),children:"Pakai Lokal"}),r.jsx(B,{size:"sm",variant:g==="server"?"primary":"secondary",disabled:s===_,onClick:()=>m(p,"server"),children:"Pakai Server"})]})]},_)})]})}function yb({label:e,data:t,at:a,ver:n,active:i}){return r.jsxs("div",{style:{border:i?"1px solid var(--brass)":"1px solid var(--line)",borderRadius:6,padding:8},children:[r.jsxs("div",{style:{fontSize:12,fontWeight:600},children:[e," · v",n]}),r.jsx("div",{style:{fontSize:11,color:"var(--text-muted)",marginBottom:4},children:new Date(a).toLocaleString()}),r.jsx("pre",{style:{fontSize:11,whiteSpace:"pre-wrap",margin:0,maxHeight:200,overflow:"auto"},children:toe(t)})]})}let Mp=null;function noe(){const[e,t]=f.useState(!1);return f.useEffect(()=>{Mp||(Mp=(async()=>{var n;try{return((n=(await F.getConfig()).sync)==null?void 0:n.running)??!1}catch{return!1}})());let a=!0;return Mp.then(n=>{a&&t(n)}),()=>{a=!1}},[]),e}function hA({onDone:e,onToast:t}){const a=noe(),[n,i]=f.useState(""),[s,o]=f.useState(!1);if(!a)return null;async function l(c){i(c?"full":"once");try{const d=c?await F.syncNow({full:!0}):await F.syncNow();d.ok?t(`Sinkron: ↓${d.pulled??0} ↑${d.pushed??0}${d.conflicts?` · ${d.conflicts} konflik`:""}`,d.conflicts?"warn":"ok",d.conflicts?"triangle-alert":"check"):t("Instance ini hub — tak ada sync manual","info","info"),d.ok&&d.conflicts&&o(!0),e()}catch{t("Gagal sync","err","x-circle")}finally{i("")}}return r.jsxs(r.Fragment,{children:[r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"rotate-ccw",onClick:()=>l(!1),disabled:n!=="",children:n==="once"?"Menyinkron…":"Sync"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"history",onClick:()=>l(!0),disabled:n!=="",title:"Tarik ulang seluruh feed dari awal — untuk data lama yang tak ikut tersinkron",children:n==="full"?"Menarik ulang…":"Tarik ulang"}),r.jsx(aoe,{open:s,onClose:()=>o(!1),onResolved:e})]})}const Sb={qa:{label:"QA finding",icon:"bug",tone:"err",color:"var(--clay-500)"},audit:{label:"Audit",icon:"search",tone:"info",color:"var(--wind-600)"},brief:{label:"feature brief",icon:"lightbulb",tone:"brass",color:"var(--brass-500)"},goal:{label:"Goal",icon:"target",tone:"brass",color:"var(--brass-600)"},help:{label:"Help Center",icon:"life-buoy",tone:"info",color:"var(--wind-500)"}},Sn=e=>Sb[e]??Sb.brief,ioe=Rc.options.map(e=>({value:e,label:Sn(e).label})),pA=[["context","Konteks","mis. operator harus membuka tiga layar untuk tahu sesi mana yang menunggu"],["outcome","Outcome","mis. satu badge di Overview menunjukkan jumlah sesi yang menunggu"],["constraints","Constraints","mis. reuse queue yang ada"]],mA=[["goal","Goal","mis. p95 GET /api/specs di bawah 200 ms"],["done","Selesai bila","mis. output benchmark menunjukkan < 200 ms"],["constraints","Batasan","mis. tanpa cache eksternal"]],_A=[["severity","Severity",""],["steps","Langkah reproduksi",`1. Buka …
7484
7484
  2. Lakukan …
7485
7485
  3. Amati …`],["expected","Diharapkan","mis. total funnel sama dengan jumlah baris laporan harian"],["actual","Aktual","mis. total funnel dua kali lipat untuk sesi yang melewati tengah malam"],["env","Environment","prod · web · v0.9.2"]],vb={brief:pA,qa:_A,goal:mA},gA=[{value:"tinggi",label:"Tinggi"},{value:"sedang",label:"Sedang"},{value:"rendah",label:"Rendah"}],fA=[{value:"critical",label:"Critical"},{value:"major",label:"Major"},{value:"minor",label:"Minor"}];function roe({spec:e,onClose:t,onSubmit:a}){var _;const n=e.stage!=="brainstorming"||e.baseSha!=null,i=ioe.filter(S=>S.value!==e.source&&(!n||mc(S.value)===mc(e.source))),[s,o]=f.useState(((_=i[0])==null?void 0:_.value)??""),l=f.useMemo(()=>Z4(s,e.payload),[s,e.payload]),[c,d]=f.useState(()=>l.payload);f.useEffect(()=>{d(l.payload)},[s]);const h=S=>y=>d(v=>({...v,[S]:y.target.value})),m=P0(s),p=vb[m]??[],g=S=>{var y;return((y=(vb[B0(e.payload)]??[]).find(([v])=>v===S))==null?void 0:y[1])??S};return i.length?r.jsxs(Tt,{open:!0,title:"Ubah type backlog item",icon:"shuffle",eyebrow:`${e.id} · ${Sn(e.source).label}`,onClose:t,children:[r.jsx(fe,{label:"Type tujuan",children:r.jsx(xe,{"aria-label":"Type tujuan",value:s,onChange:S=>o(S.target.value),options:i,style:{width:"100%"}})}),n?r.jsxs("div",{style:{fontSize:13,color:"var(--text-muted)",lineHeight:1.5,marginBottom:12},children:["Item ini sudah pernah dikerjakan sesi. Yang berpindah hanya ",r.jsx("strong",{children:"labelnya"})," — isi, worktree, dan berkas fase tak disentuh, dan hanya type dengan alur kerja yang sama yang ditawarkan."]}):r.jsxs(r.Fragment,{children:[l.dropped.length>0&&r.jsxs("div",{"data-testid":"source-dropped",style:{fontSize:12.5,color:"var(--text-muted)",lineHeight:1.5,marginBottom:12,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",padding:10},children:[r.jsx(Ne,{tone:"warn",size:"sm",children:"tak punya padanan"})," ",l.dropped.map(g).join(", ")," tidak ada di bentuk"," ",Sn(s).label,". Teks lamanya tetap tersimpan di"," ",r.jsx("strong",{children:"jejak konversi"})," item ini."]}),m!=="qa"&&r.jsx(fe,{label:"Prioritas",children:r.jsx(xe,{"aria-label":"Prioritas",value:c.priority??"sedang",onChange:h("priority"),options:gA,style:{width:"100%"}})}),p.map(([S,y,v])=>r.jsx(fe,{label:y,children:S==="severity"?r.jsx(xe,{"aria-label":y,value:c[S]??"minor",onChange:h(S),options:fA,style:{width:"100%"}}):r.jsx(Ta,{"aria-label":y,value:c[S]??"",onChange:h(S),rows:2,placeholder:v})},S))]}),r.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",marginTop:8},children:[r.jsx(B,{size:"sm",variant:"secondary",onClick:t,children:"Batal"}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"shuffle",onClick:()=>a(s,n?void 0:{...c}),children:"Ubah type"})]})]}):null}const Zn=[{key:"brainstorming",label:"Brainstorm"},{key:"objective",label:"Objective"},{key:"spec-ready",label:"Spec"},{key:"planned",label:"Plan"},{key:"executing",label:"Execute"},{key:"done",label:"Done"}],yA=e=>Zn.findIndex(t=>t.key===e),li={tinggi:{tone:"err",label:"prioritas tinggi"},sedang:{tone:"neutral",label:"prioritas sedang"},rendah:{tone:"neutral",label:"prioritas rendah"}},SA=e=>e==="missing"?"tak ditemukan":e==="unmerged"?"belum ter-merge":"belum selesai";function _2({spec:e}){const t=e.blockedBy??[];return t.length?r.jsx(Ne,{tone:"warn",size:"sm",icon:"lock",title:t.map(a=>`${a.id} — ${SA(a.reason)}`).join(" · "),children:"Terblokir"}):null}function g2({stage:e}){var n;const t=yA(e),a=((n=Zn[t])==null?void 0:n.label)??e;return r.jsx("div",{"aria-label":`Status ${a}`,style:{display:"flex",alignItems:"center",gap:4},children:Zn.map((i,s)=>{const o=s<t||e==="done",l=s===t&&e!=="done";return r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4},children:[r.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:5,padding:l?"3px 9px":0,borderRadius:"var(--radius-pill)",background:l?"var(--brass-100)":"transparent"},children:[r.jsx("span",{style:{width:8,height:8,borderRadius:"50%",background:o?"var(--leaf-500)":l?"var(--brass-500)":"var(--bone-400)"}}),l&&r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,fontWeight:500,color:"var(--brass-700)"},children:i.label})]}),s<Zn.length-1&&r.jsx("span",{style:{width:12,height:1.5,background:s<t||e==="done"?"var(--leaf-500)":"var(--bone-300)"}})]},i.key)})})}function bb({label:e,value:t}){return r.jsxs("div",{style:{marginBottom:14},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:e}),r.jsx("div",{style:{fontSize:13.5,color:"var(--text-strong)",lineHeight:1.5,whiteSpace:"pre-wrap"},children:t||"—"})]})}const soe={qa:"Finding QA — ada yang perlu diperbaiki.",brief:"Feature brief — kebutuhan yang bentuknya sudah jelas.",prd:"PRD — kebutuhan produk yang perlu didefinisikan dulu."},Ap=(e,t)=>e&&e.target===t?"primary":"secondary",Eb=e=>e==="audit";function ooe({spec:e,onClose:t,onEditBranch:a,onRevertStage:n,onOpenReview:i,onStart:s,onIntegrate:o,onEditSpec:l,onPromoteToQa:c,onPromoteToBrief:d,onPromoteToPrd:h,onEditDeps:m,onEditAutoMerge:p,onChangeSource:g,projectPolicy:_,allSpecs:S}){var lt,Ze,We;const[y,v]=f.useState([]),[b,E]=f.useState(new Set),[k,T]=f.useState(null),[A,M]=f.useState(""),[x,P]=f.useState(!1),R=f.useRef(!1),[G,j]=f.useState(!1),[w,O]=f.useState(!1),[H,N]=f.useState(!1),[z,U]=f.useState({}),ne=(e==null?void 0:e.stage)==="brainstorming"&&(e==null?void 0:e.baseSha)==null&&!!l,Q=()=>{if(!e)return;const I=e.payload||{};U({title:e.title,priority:e.priority,...I}),N(!0)},le=I=>K=>U(te=>({...te,[I]:K.target.value})),[$,oe]=f.useState(null),V=e&&Eb(e.source)?e.id:null;f.useEffect(()=>{var K;if(oe(null),!V)return;let I=!0;return(K=F.getEscalation)==null||K.call(F,V).then(te=>{I&&oe(te.escalation)}).catch(()=>{I&&oe(null)}),()=>{I=!1}},[V]);const re=()=>{if(!e||!l)return;const I=e.source==="qa"?{title:z.title,payload:{severity:z.severity,steps:z.steps,expected:z.expected,actual:z.actual,env:z.env}}:e.source==="goal"?{title:z.title,priority:z.priority,payload:{goal:z.goal,done:z.done??"",constraints:z.constraints??"",priority:z.priority}}:{title:z.title,priority:z.priority,payload:{context:z.context,outcome:z.outcome,constraints:z.constraints,priority:z.priority}};l(e,I),N(!1)},Z=e==null?void 0:e.projectId;f.useEffect(()=>{if(!Z){v([]),E(new Set);return}let I=!0;return F.listBranches(Z).then(K=>{if(I){const te=[...new Set([...K.branches,...K.remotes])].sort();v(te),E(new Set(K.remotes.filter(De=>!K.branches.includes(De))))}}).catch(()=>{I&&(v([]),E(new Set))}),()=>{I=!1}},[Z]),f.useEffect(()=>{A&&M(""),k&&T(null)},[e==null?void 0:e.id,e==null?void 0:e.stage]);async function pe(I){if(!R.current){R.current=!0,P(!0);try{return await I()}finally{R.current=!1,P(!1)}}}async function qe(){if(!e||!n||!A)return;const I=await pe(()=>n(e,A));I&&I.pending?T({target:A,files:I.wouldDelete}):I&&M("")}async function me(){if(!e||!n||!k)return;await pe(()=>n(e,k.target,!0))&&(T(null),M(""))}function Re(){k||R.current||(N(!1),t())}if(!e)return null;const Ae=Zn.slice(0,yA(e.stage)),Me=((lt=Zn.find(I=>I.key===e.stage))==null?void 0:lt.label)??e.stage,Oe=((Ze=Zn.find(I=>I.key===A))==null?void 0:Ze.label)??A,Ke=e.source==="qa",Te=e.source==="goal",$e=e.payload||{},ht=(S??[]).filter(I=>I.projectId===e.projectId&&I.id!==e.id),_e=Ke?_A:Te?mA:pA;return r.jsxs(Tt,{open:!0,title:e.title,eyebrow:e.id+" · "+e.projectId,icon:Sn(e.source).icon,onClose:Re,children:[r.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap",marginBottom:16,alignItems:"center"},children:[r.jsx(Ne,{tone:Sn(e.source).tone,size:"sm",children:Sn(e.source).label}),r.jsx(Ne,{tone:(li[e.priority]||li.sedang).tone,size:"sm",variant:"outline",children:(li[e.priority]||li.sedang).label}),r.jsx(Ne,{tone:"neutral",size:"sm",children:e.author}),r.jsx("span",{style:{flex:1}}),ne&&!H&&r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"pencil",onClick:Q,children:"Edit"}),g&&r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"shuffle",onClick:()=>O(!0),children:"Ubah type"}),i&&r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"git-compare",onClick:()=>{i(e),t()},children:"Review perubahan"})]}),r.jsxs("div",{style:{marginBottom:18},children:[r.jsx(g2,{stage:e.stage}),e.stage==="done"&&s&&r.jsx("div",{style:{marginTop:12},children:r.jsx(B,{size:"sm",variant:"primary",leftIcon:"play",onClick:()=>s(e),children:"Buka sesi lagi"})}),Eb(e.source)&&(c||d||h)&&r.jsxs("div",{style:{marginTop:12},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Tindak lanjut"}),$&&r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",lineHeight:1.5,marginBottom:8},children:[$.target==="none"?r.jsxs("span",{children:["Audit menilai ",r.jsx("strong",{children:"cukup jawaban"})," — tak perlu perbaikan."]}):r.jsxs("span",{children:[r.jsx(Ne,{tone:"brass",size:"sm",children:"direkomendasikan hanoman"})," ",soe[$.target]]}),$.reason?r.jsx("div",{style:{marginTop:4},children:$.reason}):null]}),r.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[c&&r.jsx(B,{size:"sm",variant:Ap($,"qa"),leftIcon:"bug",onClick:()=>c(e,$),children:"Jadikan Finding QA"}),d&&r.jsx(B,{size:"sm",variant:Ap($,"brief"),leftIcon:"lightbulb",onClick:()=>d(e,$),children:"Jadikan Feature brief"}),h&&r.jsx(B,{size:"sm",variant:Ap($,"prd"),leftIcon:"scroll-text",onClick:()=>h(e,$),children:"Jadikan PRD"})]})]}),e.stage==="done"&&o&&r.jsxs("div",{style:{marginTop:12},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Integrasi"}),r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"git-merge",onClick:()=>j(!0),children:"Rebase / Merge"})]}),n&&r.jsxs("div",{style:{marginTop:12},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Ubah status"}),r.jsx("div",{style:{fontSize:13,color:"var(--text-strong)",fontWeight:600,marginBottom:6},children:`Status saat ini: ${Me}`}),Ae.length>0?r.jsxs(r.Fragment,{children:[r.jsx(xe,{size:"sm","aria-label":"Kembalikan stage",value:A,onChange:I=>M(I.target.value),disabled:x,placeholder:"Pilih status lebih awal…",options:Ae.map(I=>({value:I.key,label:"← "+I.label}))}),r.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",lineHeight:1.5,marginTop:6},children:"Status saat ini dan status berikutnya tidak dapat dipilih. Kemajuan hanya berasal dari fase sesi."}),A&&r.jsxs("div",{style:{border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",background:"var(--bone-100)",padding:10,marginTop:8,fontSize:12.5,color:"var(--text-muted)",lineHeight:1.5},children:[r.jsxs("div",{style:{color:"var(--text-strong)",fontWeight:600},children:[Me," → ",Oe]}),"Fase sesi yang sudah berjalan tidak dibatalkan. Dokumen Spec/Plan di atas target mungkin perlu dihapus setelah konfirmasi; kode dan commit tidak disentuh."]}),r.jsx("div",{style:{marginTop:8},children:r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"rotate-ccw",disabled:!A,loading:x,onClick:qe,children:"Simpan status"})})]}):r.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",lineHeight:1.5},children:[Me," adalah status paling awal. Kemajuan hanya berasal dari fase sesi."]})]})]}),(e.sourceHistory??[]).length>0&&r.jsxs("div",{style:{marginBottom:14},"data-testid":"source-trail",children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Jejak konversi type"}),r.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:(e.sourceHistory??[]).map((I,K)=>r.jsxs("div",{style:{fontSize:13,color:"var(--text-muted)"},children:[r.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-strong)"},children:[I.from," → ",I.to]})," · ",new Date(I.at).toLocaleString("id-ID")," · ",I.by]},`${I.at}-${K}`))})]}),p&&r.jsxs("div",{style:{marginBottom:14},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Auto-merge saat selesai"}),r.jsx(xe,{size:"sm","aria-label":"Auto-merge item ini",value:e.autoMerge?e.autoMerge.mode:"inherit",onChange:I=>{var te;const K=I.target.value;if(K==="inherit")return p(e,null);if(K==="off")return p(e,{...po});p(e,{...e.autoMerge??po,mode:K,branch:K==="branch"?((te=e.autoMerge)==null?void 0:te.branch)??y[0]??null:null})},options:[{value:"inherit",label:`Ikut project (${iM(rD(_,null))})`},{value:"off",label:"Tanpa auto-merge untuk item ini"},{value:"default-branch",label:"Auto-merge ke default branch repo"},{value:"branch",label:"Auto-merge ke branch tujuan…"}]}),((We=e.autoMerge)==null?void 0:We.mode)==="branch"&&r.jsx("div",{style:{marginTop:6},children:r.jsx(xe,{size:"sm","aria-label":"Branch tujuan item ini",value:e.autoMerge.branch??"",onChange:I=>p(e,{...e.autoMerge,branch:I.target.value||null}),options:[{value:"",label:"Pilih branch…"},...y.map(I=>({value:I,label:I}))]})})]}),H?r.jsx(fe,{label:"Judul",children:r.jsx(je,{value:z.title??"",onChange:le("title"),placeholder:"mis. Jadwal invoice berulang",style:{width:"100%"}})}):r.jsx(bb,{label:"Objective",value:e.objective}),r.jsxs("div",{style:{marginBottom:14},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Branch worktree"}),r.jsx(xe,{size:"sm",value:e.branchFrom??"",disabled:!y.length,onChange:I=>a&&a(e,I.target.value||null),options:oA(y,b)})]}),r.jsxs("div",{style:{marginBottom:14},children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:4},children:"Bergantung pada"}),(e.dependsOn??[]).length===0?r.jsx("div",{style:{fontSize:13,color:"var(--text-subtle)"},children:"— berdiri sendiri"}):r.jsx("div",{style:{display:"flex",flexDirection:"column",gap:4},children:(e.dependsOn??[]).map(I=>{const K=(e.blockedBy??[]).find(te=>te.id===I);return r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13},children:[r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-strong)"},children:I}),K?r.jsx(Ne,{tone:"warn",size:"sm",children:SA(K.reason)}):r.jsx(Ne,{tone:"ok",size:"sm",icon:"check",children:"selesai & ter-merge"})]},I)})}),m&&ht.length>0&&r.jsx("div",{style:{maxHeight:132,overflowY:"auto",display:"flex",flexDirection:"column",gap:6,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",padding:8,marginTop:8},children:ht.map(I=>{const K=(e.dependsOn??[]).includes(I.id);return r.jsx(gn,{"aria-label":`Bergantung pada ${I.id}`,checked:K,label:`${I.id} · ${I.title}`,onChange:()=>m(e,K?(e.dependsOn??[]).filter(te=>te!==I.id):[...e.dependsOn??[],I.id])},I.id)})})]}),H?r.jsxs(r.Fragment,{children:[!Ke&&r.jsx(fe,{label:"Prioritas",children:r.jsx(xe,{value:z.priority??"sedang",onChange:le("priority"),options:gA,style:{width:"100%"}})}),_e.map(([I,K,te])=>r.jsx(fe,{label:K,children:I==="severity"?r.jsx(xe,{value:z[I]??"major",onChange:le(I),options:fA,style:{width:"100%"}}):r.jsx(Ta,{value:z[I]??"",onChange:le(I),rows:2,placeholder:te})},I)),r.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",marginTop:8},children:[r.jsx(B,{size:"sm",variant:"secondary",onClick:()=>N(!1),children:"Batal"}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"check",onClick:re,children:"Simpan"})]})]}):_e.map(([I,K])=>r.jsx(bb,{label:K,value:$e[I]??""},I)),k&&r.jsxs(Tt,{open:!0,title:"Kembalikan stage & hapus artefak",icon:"rotate-ccw",eyebrow:e.id+" → "+k.target,onClose:x?void 0:()=>T(null),children:[r.jsxs("div",{style:{fontSize:13.5,color:"var(--text-strong)",marginBottom:12},children:[k.files.length," berkas docs akan dihapus dari disk (kode & commit tak disentuh):"]}),r.jsx("ul",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-muted)",marginBottom:16,paddingLeft:18},children:k.files.map(I=>r.jsx("li",{children:I},I))}),r.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end"},children:[r.jsx(B,{size:"sm",variant:"secondary",disabled:x,onClick:()=>T(null),children:"Batal"}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"trash-2",loading:x,onClick:me,children:"Hapus & kembalikan"})]})]}),G&&o&&r.jsx(Wf,{projectId:e.projectId,ownBranch:`hanoman/${e.id.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,eyebrow:e.id,onClose:()=>j(!1),onIntegrate:(I,K)=>{j(!1),o(e,I,K)}}),w&&g&&r.jsx(roe,{spec:e,onClose:()=>O(!1),onSubmit:(I,K)=>{O(!1),g(e,I,K)}})]})}function f2({spec:e,onStart:t,onDelete:a,onOpenRun:n,onOpenReview:i,running:s}){const[o,l]=f.useState(!1);return r.jsxs("div",{className:"hn-row-actions",style:{display:"flex",alignItems:"center",gap:8},children:[i&&r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"git-compare",onClick:()=>i(e),children:"Review"}),e.stage!=="done"&&s&&r.jsx(B,{size:"sm",variant:"secondary",leftIcon:"terminal",onClick:()=>n&&n(e),children:"Buka sesi"}),e.stage!=="done"&&!s&&r.jsx(B,{size:"sm",variant:"primary",leftIcon:"play",onClick:()=>t&&t(e),children:e.stage==="brainstorming"?"Mulai":"Lanjutkan"}),e.stage==="done"&&r.jsx(Ne,{tone:"ok",size:"sm",icon:"check-circle-2",children:"selesai"}),r.jsx(Gu,{size:"sm",variant:"ghost",icon:"file-text",label:"Lihat dokumen",onClick:()=>l(!0)}),a&&r.jsx(Gu,{size:"sm",variant:"ghost",icon:"trash-2",label:"Hapus spec",onClick:()=>a(e)}),o&&r.jsx(uA,{specId:e.id,onClose:()=>l(!1)})]})}function y2({spec:e,onOpenDetail:t,size:a=15}){return r.jsx("button",{onClick:()=>t&&t(e),style:{border:"none",background:"transparent",padding:0,textAlign:"left",cursor:"pointer",fontFamily:"var(--font-sans)",fontSize:a,fontWeight:600,color:"var(--text-strong)"},children:e.title})}function loe({spec:e,onStart:t,onDelete:a,onOpenRun:n,onOpenReview:i,onOpenDetail:s,running:o}){const l=li[e.priority]||li.sedang;return r.jsxs(be,{padding:16,children:[r.jsxs("div",{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:12},children:[r.jsxs("div",{style:{minWidth:0},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-subtle)"},children:e.id}),r.jsx(Ne,{tone:Sn(e.source).tone,size:"sm",icon:Sn(e.source).icon,children:Sn(e.source).label}),e.branchFrom&&r.jsx(Ne,{tone:"neutral",size:"sm",icon:"git-branch",children:e.branchFrom}),r.jsx(_2,{spec:e}),r.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-muted)"},children:["· ",e.projectId]})]}),r.jsx("div",{style:{marginTop:8},children:r.jsx(y2,{spec:e,onOpenDetail:s})}),r.jsx("div",{style:{fontSize:13,color:"var(--text-muted)",marginTop:4,lineHeight:1.45},children:e.objective})]}),r.jsx(Ne,{tone:l.tone,size:"sm",variant:e.priority==="tinggi"?"soft":"outline",children:l.label})]}),r.jsxs("div",{style:{marginTop:14,paddingTop:12,borderTop:"1px solid var(--border-hair)"},children:[r.jsx(g2,{stage:e.stage}),r.jsxs("div",{className:"hn-card-footer",style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:10,marginTop:12},children:[r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)"},children:e.author}),r.jsx(f2,{spec:e,onStart:t,onDelete:a,onOpenRun:n,onOpenReview:i,running:o})]})]})]})}function coe({spec:e,onStart:t,onDelete:a,onOpenRun:n,onOpenReview:i,onOpenDetail:s,running:o}){const l=li[e.priority]||li.sedang;return r.jsxs("div",{className:"hn-backlog-row",style:{display:"flex",alignItems:"center",gap:14,padding:"12px 16px",borderBottom:"1px solid var(--border-hair)",background:"var(--surface-card)"},children:[r.jsx(Ie,{name:Sn(e.source).icon,size:15,color:Sn(e.source).color}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-subtle)",flex:"0 0 84px"},children:e.id}),r.jsxs("div",{style:{flex:1,minWidth:0},children:[r.jsx(y2,{spec:e,onOpenDetail:s,size:14}),r.jsx("div",{style:{fontSize:12,color:"var(--text-muted)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.objective})]}),e.branchFrom&&r.jsx(Ne,{tone:"neutral",size:"sm",icon:"git-branch",children:e.branchFrom}),r.jsx(_2,{spec:e}),r.jsx(Ne,{tone:l.tone,size:"sm",variant:e.priority==="tinggi"?"soft":"outline",children:l.label}),r.jsx("div",{style:{flex:"0 0 auto"},children:r.jsx(g2,{stage:e.stage})}),r.jsx(f2,{spec:e,onStart:t,onDelete:a,onOpenRun:n,onOpenReview:i,running:o})]})}const Ah="backlog",vA="success",doe=Zn[0].key,kb=[{key:Ah,label:"Backlog",icon:"inbox"},...Zn.slice(0,5).map(e=>({key:e.key,label:e.label})),{key:vA,label:"Success",icon:"check-circle-2"}];function uoe(e,t){return e.stage==="done"?vA:!t&&e.stage==="brainstorming"?Ah:e.stage}const xb=(e,t)=>e===Ah&&t===doe;function hoe({spec:e,col:t,onOpenDetail:a,onStart:n,onOpenRun:i,onOpenReview:s,running:o,onDragStart:l,onDragEnd:c,dragging:d}){const h=li[e.priority]||li.sedang,m=t===Ah;return r.jsxs("div",{draggable:m,onDragStart:p=>{p.dataTransfer.effectAllowed="move",p.dataTransfer.setData("text/plain",e.id),l()},onDragEnd:c,title:m?"Seret ke Brainstorm untuk memulai sesi":"Stage mengikuti fase yang dilaporkan agen — kartu tak bisa dipindah",style:{flex:"0 0 auto",background:"var(--surface-card)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",padding:10,boxShadow:"var(--shadow-xs)",cursor:m?"grab":"default",opacity:d?.4:1},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,marginBottom:6},children:[r.jsx(Ie,{name:Sn(e.source).icon,size:13,color:Sn(e.source).color}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)"},children:e.id}),r.jsx("span",{style:{flex:1}}),r.jsx(Ne,{tone:h.tone,size:"sm",variant:e.priority==="tinggi"?"soft":"outline",children:e.priority})]}),r.jsx(y2,{spec:e,onOpenDetail:a,size:13}),e.branchFrom&&r.jsx("div",{style:{marginTop:6},children:r.jsx(Ne,{tone:"neutral",size:"sm",icon:"git-branch",children:e.branchFrom})}),(e.blockedBy??[]).length>0&&r.jsx("div",{style:{marginTop:6},children:r.jsx(_2,{spec:e})}),r.jsx("div",{style:{marginTop:8},children:r.jsx(f2,{spec:e,onStart:n,onOpenRun:i,onOpenReview:s,running:o})})]})}function poe({specs:e,activeSpecs:t,onStart:a,onOpenRun:n,onOpenReview:i,onOpenDetail:s}){const[o,l]=f.useState(null),[c,d]=f.useState(null),h=f.useMemo(()=>{var g;const p=new Map(kb.map(_=>[_.key,[]]));for(const _ of e)(g=p.get(uoe(_,t==null?void 0:t.has(_.id))))==null||g.push(_);return p},[e,t]),m=p=>{o&&xb(o.from,p)&&a&&a(o.spec),l(null),d(null)};return r.jsx("div",{"data-testid":"backlog-board",className:"hn-board-local-overflow",style:{flex:"1 1 auto",minHeight:0,display:"flex",gap:10,overflowX:"auto",overflowY:"hidden",alignItems:"stretch",paddingBottom:4},children:kb.map(p=>{const g=h.get(p.key),_=!!o&&xb(o.from,p.key),S=_&&c===p.key;return r.jsxs("div",{onDragOver:y=>{_&&(y.preventDefault(),y.dataTransfer.dropEffect="move",d(p.key))},onDragLeave:()=>d(y=>y===p.key?null:y),onDrop:y=>{y.preventDefault(),m(p.key)},style:{flex:"0 0 244px",display:"flex",flexDirection:"column",minHeight:0,padding:10,borderRadius:"var(--radius-lg)",background:S?"var(--brass-100)":"var(--bone-100)",border:`1px ${_?"dashed":"solid"} ${S?"var(--brass-500)":"var(--border-hair)"}`,opacity:o&&!_?.5:1,transition:"var(--transition-fast)"},children:[r.jsxs("div",{style:{...Mr,display:"flex",alignItems:"center",gap:6,marginBottom:8},children:[p.icon&&r.jsx(Ie,{name:p.icon,size:13,color:"var(--text-muted)"}),r.jsx("span",{className:"hn-eyebrow",children:p.label}),r.jsx("span",{style:{flex:1}}),r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)"},children:g.length})]}),r.jsx("div",{style:{...gc,display:"flex",flexDirection:"column",gap:8},children:g.map(y=>r.jsx(hoe,{spec:y,col:p.key,onOpenDetail:s,onStart:a,onOpenRun:n,onOpenReview:i,running:t==null?void 0:t.has(y.id),dragging:(o==null?void 0:o.spec.id)===y.id,onDragStart:()=>l({spec:y,from:p.key}),onDragEnd:()=>{l(null),d(null)}},y.id))})]},p.key)})})}const moe=[{value:"grid",label:"Grid",icon:"layout-grid"},{value:"list",label:"List",icon:"list"},{value:"board",label:"Board",icon:"kanban"}];function _oe({backlog:e,projects:t,pageSize:a=20,onStart:n,activeSpecs:i,onDelete:s,onOpenRun:o,onOpenReview:l,onNew:c,onEditBranch:d,onRevertStage:h,onIntegrate:m,onEditSpec:p,onEditDeps:g,onEditAutoMerge:_,onChangeSource:S,onPromoteToQa:y,onPromoteToBrief:v,onPromoteToPrd:b,projectFilter:E,onProjectFilter:k,dataVersion:T,onToast:A,initialDetailId:M}){var K;const[x,P]=rt("backlog","tab","all",Zt),[R,G]=f.useState(0),[j,w]=rt("backlog","view","grid",ri("grid","list","board")),[O,H]=rt("backlog","q","",Zt),[N,z]=rt("backlog","stage","all",Zt),[U,ne]=rt("backlog","prio","all",Zt),[Q,le]=rt("backlog","dateField","created",ri("created","started")),[$,oe]=rt("backlog","from","",Zt),[V,re]=rt("backlog","to","",Zt),Z=E,pe=k,[qe,me]=rt("backlog","detailId",null,Io);f.useEffect(()=>{M&&me(M)},[M]);const Re=t||[...new Set(e.map(te=>te.projectId))].map(te=>({id:te,name:te})),[Ae,Me]=f.useState(()=>({items:e,total:e.length})),[Oe,Ke]=rt("backlog","page",1,Hi),[Te,$e]=f.useState(""),ht=[x!=="all",Z!=="all",O.trim()!=="",N!=="all",U!=="all",$!=="",V!==""].filter(Boolean).length,_e=wh("backlog","scroll",Ae.items.length>0),lt=()=>pe("all");f.useEffect(()=>{const te=setTimeout(()=>$e(O.trim()),250);return()=>clearTimeout(te)},[O]),f.useEffect(()=>{Ke(1)},[x,Z,N,U,Te,j,Q,$,V]),f.useEffect(()=>{var ce;let te=!0;const De=(ce=F.listSpecs)==null?void 0:ce.call(F,{project:Z==="all"?void 0:Z,source:x==="all"?void 0:x,q:Te||void 0,stage:N==="all"?void 0:N,priority:U==="all"?void 0:U,dateField:$||V?Q:void 0,from:$||void 0,to:V||void 0,page:j==="board"?void 0:Oe,limit:j==="board"?void 0:a});return De==null||De.then(J=>{te&&Me({items:J.items,total:J.total})}).catch(()=>{}),()=>{te=!1}},[x,Z,N,U,Te,j,Oe,a,T,R,Q,$,V]);const Ze=f.useMemo(()=>new Map(e.map(te=>[te.id,te])),[e]),We=f.useMemo(()=>Ae.items.map(te=>Ze.get(te.id)??te),[Ae.items,Ze]),I=gi(Ae.total,Oe,a);return r.jsxs("div",{style:J0,children:[r.jsxs("div",{className:"hn-backlog-controls",role:"region","aria-label":"Kontrol backlog",style:{...Mr,marginBottom:18},children:[r.jsxs("div",{className:"hn-backlog-topline",style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:12,flexWrap:"wrap",marginBottom:12},children:[r.jsx(mi,{"aria-label":"Sumber backlog",variant:"pill",value:x,onChange:P,tabs:[{value:"all",label:"Semua spec"},{value:"brief",label:"Dari brief"},{value:"qa",label:"Dari QA"},{value:"audit",label:"Audit"},{value:"goal",label:"Goal"},{value:"help",label:"Help Center"}]}),r.jsxs("div",{className:"hn-backlog-view-actions",style:{display:"flex",alignItems:"center",gap:10},children:[r.jsx(mi,{variant:"pill",value:j,onChange:w,tabs:moe,"aria-label":"Mode tampilan"}),r.jsx(hA,{onDone:()=>G(te=>te+1),onToast:A??(()=>{})}),r.jsx(Mh,{screen:"backlog",active:ht,onReset:lt}),r.jsxs("span",{className:"hn-eyebrow",children:[Ae.total," spec"]})]})]}),r.jsxs("div",{className:"hn-backlog-filters",style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[r.jsx(je,{size:"sm",leftIcon:"search",placeholder:"mis. invoice atau SPEC-412","aria-label":"Cari backlog",value:O,onChange:te=>H(te.target.value),style:{flex:"1 1 220px"}}),r.jsx(xe,{size:"sm","aria-label":"Filter project",value:Z,onChange:te=>pe(te.target.value),options:[{value:"all",label:"Semua project"}].concat(Re.map(te=>({value:te.id,label:te.name})))}),r.jsx(xe,{size:"sm","aria-label":"Filter stage",value:N,onChange:te=>z(te.target.value),options:[{value:"all",label:"Semua stage"}].concat(Zn.map(te=>({value:te.key,label:te.label})))}),r.jsx(xe,{size:"sm","aria-label":"Filter prioritas",value:U,onChange:te=>ne(te.target.value),options:[{value:"all",label:"Semua prioritas"},{value:"tinggi",label:"Tinggi"},{value:"sedang",label:"Sedang"},{value:"rendah",label:"Rendah"}]}),r.jsx(xe,{size:"sm","aria-label":"Filter tanggal berdasarkan",value:Q,onChange:te=>le(te.target.value),options:[{value:"created",label:"Dibuat"},{value:"started",label:"Dikerjakan"}]}),r.jsx(je,{size:"sm",type:"date","aria-label":"Tanggal dari",value:$,onChange:te=>oe(te.target.value),style:{flex:"0 0 auto"}}),r.jsx("span",{className:"hn-eyebrow","aria-hidden":"true",children:"→"}),r.jsx(je,{size:"sm",type:"date","aria-label":"Tanggal sampai",value:V,onChange:te=>re(te.target.value),style:{flex:"0 0 auto"}})]})]}),Ae.total===0?e.length===0?r.jsx(ue,{kind:"empty",illustration:"PST-002",title:"Backlog masih kosong",hint:"Filekan feature brief atau QA finding — hanoman menjalankannya dari brainstorm sampai execute.",action:c,actionLabel:"Tambah spec"}):r.jsx(ue,{kind:"empty",icon:"filter",title:"Tidak ada spec untuk filter ini",hint:`${e.length} spec ada di backlog, tapi tak ada yang cocok dengan filter aktif.`,action:()=>{P("all"),pe("all"),H(""),z("all"),ne("all"),le("created"),oe(""),re("")},actionLabel:"Reset filter",actionIcon:"rotate-ccw"}):j==="board"?r.jsx(poe,{specs:We,activeSpecs:i,onStart:n,onOpenRun:o,onOpenReview:l,onOpenDetail:te=>me(te.id)}):r.jsxs(r.Fragment,{children:[j==="list"?r.jsx("div",{ref:_e,"data-testid":"backlog-scroll",className:"hn-backlog-list",style:{...gc,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflowX:"hidden"},children:We.map(te=>r.jsx(coe,{spec:te,onStart:n,running:i==null?void 0:i.has(te.id),onDelete:s,onOpenRun:o,onOpenReview:l,onOpenDetail:De=>me(De.id)},te.id))}):r.jsx("div",{ref:_e,"data-testid":"backlog-scroll",className:"hn-backlog-grid",style:{...gc,display:"grid",gap:12,gridTemplateColumns:"repeat(auto-fill, minmax(340px, 1fr))"},children:We.map(te=>r.jsx(loe,{spec:te,onStart:n,running:i==null?void 0:i.has(te.id),onDelete:s,onOpenRun:o,onOpenReview:l,onOpenDetail:De=>me(De.id)},te.id))}),r.jsx("div",{style:{...Mr,marginTop:14,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-lg)",overflow:"hidden"},children:r.jsx(fi,{page:I.page,pageCount:I.pageCount,total:Ae.total,from:I.from,to:I.to,onPage:Ke,unit:"spec"})})]}),r.jsx(ooe,{spec:e.find(te=>te.id===qe)||null,onClose:()=>me(null),onEditBranch:d,onRevertStage:h,onOpenReview:l,onStart:n,onIntegrate:m,onEditSpec:p,onPromoteToQa:y,onPromoteToBrief:v,onPromoteToPrd:b,onEditDeps:g,onEditAutoMerge:_,onChangeSource:S,projectPolicy:(K=t.find(te=>{var De;return te.id===((De=e.find(ce=>ce.id===qe))==null?void 0:De.projectId)}))==null?void 0:K.autoMerge,allSpecs:e})]})}const goe=5e3,S2=20;function bA({total:e,page:t,onPage:a,unit:n="tiket"}){const i=gi(e,t,S2);return r.jsx(fi,{page:i.page,pageCount:i.pageCount,total:e,from:i.from,to:i.to,onPage:a,unit:n})}function EA(e,t=Date.now()){const a=Math.max(0,t-new Date(e).getTime()),n=Math.floor(a/6e4);if(n<1)return"baru saja";if(n<60)return`${n}m`;const i=Math.floor(n/60);return i<24?`${i}j`:`${Math.floor(i/24)}h`}const kA={new:"warn",accepted:"ok",rejected:"neutral"},xA={new:"belum ditinjau",accepted:"diterima",rejected:"ditutup"};function foe({t:e,onOpen:t}){return r.jsxs("button",{onClick:()=>t(e.id),className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:12,width:"100%",textAlign:"left",padding:"12px 14px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",background:"var(--surface-card)",cursor:"pointer",marginBottom:8},children:[r.jsxs("span",{style:{flex:1,minWidth:0},children:[r.jsxs("span",{style:{display:"flex",alignItems:"center",gap:8},children:[r.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:["#",e.number]}),r.jsx(Ne,{tone:"neutral",size:"sm",children:e.category}),r.jsx(Ne,{tone:kA[e.status]??"neutral",size:"sm",children:xA[e.status]??e.status})]}),r.jsx("span",{style:{display:"block",color:"var(--text-body)",fontSize:"var(--text-sm)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:e.title}),r.jsxs("span",{style:{fontSize:"var(--text-xs)",color:"var(--text-subtle)",marginTop:2,display:"block"},children:[e.projectId," · ",e.reporterEmail," · ",EA(e.createdAt)," lalu",e.attachmentCount>0?` · ${e.attachmentCount} lampiran`:""]})]}),e.specId&&r.jsxs(Ne,{tone:"ok",icon:"link",children:["→ ",e.specId]}),r.jsx(Ie,{name:"chevron-right",size:16,color:"var(--text-subtle)"})]})}function yoe({id:e,onBack:t,onAccepted:a,onDeleted:n,onToast:i}){var G;const[s,o]=f.useState(null),[l,c]=f.useState("loading"),[d,h]=f.useState(!1),[m,p]=f.useState("sedang"),[g,_]=f.useState(!1),[S,y]=f.useState(!1),[v,b]=f.useState({title:"",detail:"",category:"bug",status:"new"}),E=f.useCallback(()=>{F.getTicket(e).then(j=>{o(j),c("ready")}).catch(()=>c("error"))},[e]);if(f.useEffect(()=>{E()},[E]),l==="loading")return r.jsx(ue,{kind:"loading"});if(l==="error"||!s)return r.jsx(ue,{kind:"error",hint:"Gagal memuat tiket.",action:E,actionLabel:"Coba lagi"});async function k(){h(!0);try{const j=await F.acceptTicket(e,m);a(j.spec,!!j.alreadyPromoted)}catch{i("Gagal menerima tiket","err","x-circle")}finally{h(!1)}}async function T(){if(window.confirm(`Tolak & tutup tiket #${s.number}? Tak membuat backlog.`)){h(!0);try{await F.rejectTicket(e),o({...s,status:"rejected"}),i("Tiket ditutup","ok","check")}catch{i("Gagal menolak tiket","err","x-circle")}finally{h(!1)}}}async function A(){h(!0);try{const j=await F.unlinkTicket(e);o({...s,specId:j.specId,spec:null,status:j.status}),i("Tautan backlog dilepas","ok","unlink")}catch{i("Gagal melepas tautan","err","x-circle")}finally{h(!1)}}function M(){b({title:s.title,detail:s.detail,category:s.category,status:s.status}),_(!0)}async function x(){h(!0);try{const j=await F.editTicket(e,{title:v.title,detail:v.detail,category:v.category,status:v.status});o(j),_(!1),i("Tiket diperbarui","ok")}catch{i("Gagal menyimpan","err","x-circle")}finally{h(!1)}}async function P(){h(!0);try{await F.deleteTicket(e),i("Tiket dihapus","ok","trash-2"),n()}catch{i("Gagal menghapus","err","x-circle"),h(!1)}}if(g)return r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10},children:[r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:()=>_(!1),disabled:d,children:"Batal"}),r.jsx("span",{style:{flex:1}}),r.jsx(B,{size:"sm",variant:"primary",leftIcon:"check",onClick:x,disabled:d,children:"Simpan"})]}),r.jsx(fe,{label:"Judul",children:r.jsx(je,{value:v.title,placeholder:"mis. Tombol Simpan tak berfungsi di HP",onChange:j=>b({...v,title:j.target.value})})}),r.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[r.jsx(fe,{label:"Kategori",children:r.jsx(xe,{value:v.category,onChange:j=>b({...v,category:j.target.value}),options:[{value:"bug",label:"bug"},{value:"fitur",label:"fitur"},{value:"pertanyaan",label:"pertanyaan"},{value:"lainnya",label:"lainnya"}]})}),r.jsx(fe,{label:"Status",children:r.jsx(xe,{value:v.status,onChange:j=>b({...v,status:j.target.value}),options:[{value:"new",label:"belum ditinjau"},{value:"accepted",label:"diterima"},{value:"rejected",label:"ditutup"}]})})]}),r.jsx(fe,{label:"Detail keluhan",children:r.jsx(Ta,{value:v.detail,rows:6,placeholder:"mis. Buka halaman Pesanan di HP, tekan Simpan — layar diam dan datanya tak tersimpan.",onChange:j=>b({...v,detail:j.target.value})})})]});const R=s.status!=="new";return r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:t,children:"Kembali"}),r.jsx(Ne,{tone:kA[s.status]??"neutral",children:xA[s.status]??s.status}),r.jsx("span",{style:{flex:1}}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"pencil",onClick:M,disabled:d,children:"Ubah"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"trash-2",onClick:()=>y(!0),disabled:d,children:"Hapus"}),s.publicStatusUrl&&r.jsxs(r.Fragment,{children:[r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"share-2",onClick:()=>window.open(s.publicStatusUrl,"_blank","noreferrer"),children:"Buka status publik"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"link-2",onClick:()=>{var j;(j=navigator.clipboard)==null||j.writeText(s.publicStatusUrl),i("Link publik disalin","ok","copy")},children:"Salin link publik"})]}),s.specId?r.jsxs(r.Fragment,{children:[r.jsxs(Ne,{tone:"ok",icon:"link",children:["→ ",s.specId]}),r.jsx(Ne,{tone:"neutral",size:"sm",children:$D(s.status,(G=s.spec)==null?void 0:G.stage)}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"external-link",onClick:()=>window.open(Yf(s.specId),"_blank","noreferrer"),children:"Buka backlog"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"copy",onClick:()=>{var j;(j=navigator.clipboard)==null||j.writeText(Yf(s.specId)),i("Link backlog disalin","ok","copy")},children:"Salin link"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"unlink",onClick:A,disabled:d,children:"Lepas tautan"})]}):!R&&r.jsxs(r.Fragment,{children:[r.jsx(xe,{size:"sm",value:m,onChange:j=>p(j.target.value),options:[{value:"tinggi",label:"Prioritas tinggi"},{value:"sedang",label:"Prioritas sedang"},{value:"rendah",label:"Prioritas rendah"}]}),r.jsx(B,{size:"sm",leftIcon:"arrow-up-right",onClick:k,disabled:d,children:"Terima → backlog"}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"ban",onClick:T,disabled:d,children:"Tolak"})]})]}),r.jsxs("div",{children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[r.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:["#",s.number]}),r.jsx(Ne,{tone:"neutral",size:"sm",children:s.category})]}),r.jsx("div",{style:{fontWeight:600,fontSize:"var(--text-lg)",color:"var(--text-strong)",marginTop:4},children:s.title})]}),r.jsxs("div",{style:{display:"flex",gap:18,flexWrap:"wrap",fontSize:"var(--text-sm)",color:"var(--text-muted)"},children:[r.jsxs("span",{children:["pelapor: ",r.jsx("b",{style:{color:"var(--text-body)"},children:s.reporterEmail})]}),r.jsxs("span",{children:["project: ",r.jsx("b",{style:{color:"var(--text-body)"},children:s.projectId})]}),r.jsxs("span",{children:["masuk: ",EA(s.createdAt)," lalu"]})]}),r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Detail keluhan"}),r.jsx("div",{style:{whiteSpace:"pre-wrap",color:"var(--text-body)",fontSize:"var(--text-sm)",lineHeight:1.55},children:s.detail})]}),s.attachments.length>0&&r.jsxs("div",{children:[r.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Lampiran"}),r.jsx("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:s.attachments.map(j=>r.jsx("a",{href:q.ticketAttachment(s.id,j.id),target:"_blank",rel:"noreferrer",style:{display:"block",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden"},children:r.jsx("img",{src:q.ticketAttachment(s.id,j.id),alt:j.filename,style:{display:"block",maxWidth:180,maxHeight:140,objectFit:"cover"}})},j.id))})]}),r.jsx(Ch,{open:S,title:"Hapus tiket?",eyebrow:`#${s.number}`,message:`Tiket "${s.title}" dan seluruh lampirannya akan dihapus permanen. Tindakan ini tak bisa dibatalkan.`,busy:d,onCancel:()=>y(!1),onConfirm:P})]})}function Soe({projectId:e,onAccepted:t}){const[a,n]=f.useState([]),[i,s]=f.useState("loading"),[o,l]=f.useState(!1),[c,d]=f.useState(null),[h,m]=f.useState(null),[p,g]=f.useState([]),[_,S]=f.useState(0),[y,v]=f.useState(1),b=f.useCallback(async()=>{try{const x=await F.listGithubIssues(e,{page:y,limit:S2});n(x.items),S(x.total),s("ready")}catch{s("error")}},[e,y]);f.useEffect(()=>{b()},[b]);const E=x=>{var R;const P=(R=x.detail)==null?void 0:R.error;return typeof P=="string"?P:x.message};async function k(){l(!0),m(null),d(null);try{const x=await F.pullGithubIssues(e);d(`${x.repo}: ${x.created} baru, ${x.updated} diperbarui`+(x.skippedPullRequests?` · ${x.skippedPullRequests} pull request dilewati`:"")),await b()}catch(x){m(E(x))}finally{l(!1)}}async function T(){l(!0),m(null);try{const x=await F.acceptGithubIssues(p,void 0);g([]),t==null||t(x.created),await b()}catch(x){m(E(x))}finally{l(!1)}}async function A(x){l(!0),m(null);try{await F.rejectGithubIssue(x),await b()}catch(P){m(E(P))}finally{l(!1)}}const M=x=>g(P=>P.includes(x)?P.filter(R=>R!==x):[...P,x]);return r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12,minHeight:0,flex:1},children:[r.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",flexWrap:"wrap"},children:[r.jsx(B,{size:"sm",onClick:k,disabled:o,children:"Tarik issue"}),r.jsxs(B,{size:"sm",variant:"primary",onClick:T,disabled:o||p.length===0,children:["Terima terpilih",p.length?` (${p.length})`:""]}),c&&r.jsx("span",{style:{fontSize:12,color:"var(--text-muted)"},children:c})]}),h&&r.jsx("div",{role:"alert",style:{fontSize:12,color:"var(--danger, #b00)"},children:h}),i==="loading"?r.jsx(ue,{kind:"loading"}):i==="error"?r.jsx(ue,{kind:"error",hint:"Gagal memuat daftar issue.",action:()=>void b(),actionLabel:"Coba lagi"}):a.length===0?r.jsx(ue,{kind:"empty",icon:"inbox",title:"Belum ada issue tertarik",hint:"Tekan “Tarik issue” untuk menariknya dari repo GitHub project ini."}):r.jsxs(r.Fragment,{children:[r.jsx("div",{style:{overflowY:"auto",minHeight:0},children:a.map(x=>r.jsxs("div",{className:"hn-dense-row",style:{display:"flex",gap:8,alignItems:"baseline",padding:"8px 0",borderBottom:"1px solid var(--border-hair)"},children:[x.status==="new"&&r.jsx("input",{type:"checkbox","aria-label":`Pilih issue ${x.number}`,checked:p.includes(x.id),onChange:()=>M(x.id)}),r.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-muted)"},children:["#",x.number]}),r.jsx("a",{href:x.url,target:"_blank",rel:"noreferrer",style:{flex:1,minWidth:0},children:x.title}),r.jsxs("span",{style:{fontSize:12,color:"var(--text-muted)"},children:["@",x.authorLogin]}),x.labels.map(P=>r.jsx(Ne,{children:P},P)),x.status==="rejected"&&r.jsx(Ne,{tone:"neutral",children:"ditutup"}),x.specId&&r.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12},children:x.specId}),x.status==="new"&&r.jsx(B,{size:"sm",variant:"ghost",onClick:()=>A(x.id),disabled:o,children:"Tolak"})]},x.id))}),r.jsx(bA,{total:_,page:y,onPage:v,unit:"issue"})]})]})}function voe({projects:e,onAccepted:t,onToast:a}){const[n,i]=f.useState([]),[s,o]=f.useState(0),[l,c]=rt("triage","page",1,Hi),[d,h]=f.useState(0),[m,p]=f.useState("loading"),[g,_]=rt("triage","openId",null,Io),[S,y]=rt("triage","project","",Zt),[v,b]=rt("triage","status","",Zt),[E,k]=rt("triage","q","",Zt),[T,A]=rt("triage","tab","tiket",ri("tiket","issue")),M=[S!=="",v!=="",E.trim()!==""].filter(Boolean).length,x=wh("triage","scroll",n.length>0),P=f.useCallback((j=!1)=>{j||p("loading"),F.listTickets({project:S||void 0,status:v||void 0,q:E||void 0,page:String(l),limit:String(S2)}).then(w=>{i(w.items),o(w.total),h(w.unreviewed),p("ready")}).catch(()=>{j||p("error")})},[S,v,E,l]);f.useEffect(()=>{P()},[P]),f.useEffect(()=>{c(1)},[S,v,E]),f.useEffect(()=>{const j=setInterval(()=>{document.hidden||P(!0)},goe);return()=>clearInterval(j)},[P]);const R=r.jsx("div",{style:{display:"flex",flexDirection:"column",gap:12,minHeight:0,flex:1},children:S?r.jsx(Soe,{projectId:S,onAccepted:j=>j.forEach(w=>t(w,!1))}):r.jsx(ue,{kind:"empty",icon:"inbox",title:"Pilih satu project",hint:"Issue GitHub milik satu repo, jadi pilih project-nya lebih dulu di penyaring di atas."})}),G=r.jsx("div",{style:{display:"flex",flexDirection:"column",flex:1,minHeight:0},children:m==="loading"?r.jsx(ue,{kind:"loading"}):m==="error"?r.jsx(ue,{kind:"error",hint:"Gagal memuat tiket.",action:()=>P(),actionLabel:"Coba lagi"}):n.length===0?r.jsx(ue,{kind:"empty",icon:"inbox",title:"Belum ada keluhan",hint:"Aktifkan Help Center di detail project, lalu sebar link publiknya agar keluhan mulai masuk."}):r.jsxs(r.Fragment,{children:[r.jsx("div",{ref:x,"data-testid":"triage-scroll",style:{overflowY:"auto",minHeight:0,flex:"1 1 auto"},children:n.map(j=>r.jsx(foe,{t:j,onOpen:_},j.id))}),r.jsx(bA,{total:s,page:l,onPage:c})]})});return r.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14,minHeight:0,flex:1},children:[r.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",gap:8,alignItems:"center"},children:[r.jsx(B,{size:"sm",variant:T==="tiket"?"primary":"ghost",onClick:()=>A("tiket"),children:"Tiket Help Center"}),r.jsx(B,{size:"sm",variant:T==="issue"?"primary":"ghost",onClick:()=>A("issue"),children:"Issue GitHub"})]}),r.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap",alignItems:"center"},children:[r.jsx(xe,{size:"sm",value:S,"aria-label":"Project triase",onChange:j=>y(j.target.value),options:[{value:"",label:"Semua project"},...e.map(j=>({value:j.id,label:j.name}))]}),T==="tiket"&&r.jsxs(r.Fragment,{children:[r.jsx(xe,{size:"sm",value:v,"aria-label":"Status tiket",onChange:j=>b(j.target.value),options:[{value:"",label:"Semua status"},{value:"new",label:"belum ditinjau"},{value:"accepted",label:"diterima"},{value:"rejected",label:"ditutup"}]}),r.jsx(je,{size:"sm",value:E,"aria-label":"Cari tiket",onChange:j=>k(j.target.value),placeholder:"mis. gagal login atau budi@contoh.id",style:{flex:1,minWidth:160}}),d>0&&r.jsxs(Ne,{tone:"warn",children:[d," belum ditinjau"]}),r.jsx(hA,{onDone:()=>P(!0),onToast:a}),r.jsx(Mh,{screen:"triage",active:M})]})]}),T==="issue"?R:r.jsx(No,{ariaLabel:"Panel triase",active:g?"detail":"list",onActiveChange:j=>{j==="list"&&_(null)},splitAt:"tablet",masterWidth:360,panels:[{id:"list",label:"Daftar",content:G,className:"hn-panel-flex"},...g?[{id:"detail",label:"Detail",className:"hn-panel-flex",content:r.jsx(yoe,{id:g,onBack:()=>{_(null),P(!0)},onAccepted:t,onDeleted:()=>{_(null),P(!0)},onToast:a})}]:[]]})]})}function TA({projects:e,defaultProject:t,onClose:a,onCreate:n,prefill:i,lockProject:s}){var p;const[o,l]=f.useState(t||((p=e[0])==null?void 0:p.id)||""),[c,d]=f.useState({title:(i==null?void 0:i.title)??"",context:(i==null?void 0:i.context)??"",outcome:(i==null?void 0:i.outcome)??"",constraints:(i==null?void 0:i.constraints)??""}),h=g=>_=>d(S=>({...S,[g]:_.target.value})),m=()=>{!c.title.trim()||!o||n(o,{title:c.title.trim(),context:c.context,outcome:c.outcome,constraints:c.constraints||void 0})};return r.jsxs(Tt,{open:!0,onClose:a,icon:"scroll-text",eyebrow:"PM → hanoman",title:"PRD baru",footer:r.jsxs(r.Fragment,{children:[r.jsx(B,{variant:"ghost",size:"sm",onClick:a,children:"Batal"}),r.jsx(B,{size:"sm",leftIcon:"messages-square",onClick:m,children:"Buat brief → brainstorm PRD"})]}),children:[r.jsxs("div",{style:{fontSize:12,color:"var(--text-subtle)",marginBottom:12,lineHeight:1.5},children:["hanoman membuka sesi brainstorm interaktif di terminal, lalu menulis dokumen PRD ke ",r.jsx("code",{children:"docs/prd/"}),"."]}),r.jsx(fe,{label:"Project",hint:"Tujuan penulisan docs/prd/ — pilih di sini, tak perlu memfilter daftar dulu",children:r.jsx(xe,{"aria-label":"Project untuk PRD baru",value:o,disabled:s,onChange:g=>l(g.target.value),style:{width:"100%"},options:e.map(g=>({value:g.id,label:g.name}))})}),r.jsx(fe,{label:"Judul",children:r.jsx(je,{value:c.title,onChange:h("title"),placeholder:"mis. Jadwal Invoice Berulang",style:{width:"100%"}})}),r.jsx(fe,{label:"Konteks",hint:"Latar belakang & alasan fitur ini dibutuhkan",children:r.jsx(Ta,{value:c.context,onChange:h("context"),rows:3,placeholder:"mis. operator harus membuka tiga layar untuk tahu sesi mana yang menunggu"})}),r.jsx(fe,{label:"Hasil yang diharapkan",children:r.jsx(Ta,{value:c.outcome,onChange:h("outcome"),rows:2,placeholder:"mis. satu badge di Overview menunjukkan jumlah sesi yang menunggu"})}),r.jsx(fe,{label:"Batasan",hint:"opsional",children:r.jsx(je,{value:c.constraints,onChange:h("constraints"),placeholder:"mis. reuse queue yang ada",style:{width:"100%"}})})]})}const boe={draft:"neutral",dieskalasi:"info",terwujud:"ok"};function CA({prd:e}){return r.jsx(Ne,{tone:boe[e.status],size:"sm",children:e.specCount>0?`${e.status} ${e.doneCount}/${e.specCount}`:e.status})}function Eoe({prd:e,projectId:t,onTake:a,onStartBreakdown:n,onMaterialize:i}){const[s,o]=f.useState(null),[l,c]=f.useState([]),[d,h]=f.useState([]),[m,p]=f.useState(!1),[g,_]=f.useState(!1);f.useEffect(()=>{let b=!0;return o(null),F.getPrd(t,e.path).then(E=>{b&&o(E.content)}).catch(()=>{b&&o("")}),()=>{b=!1}},[t,e.path]),f.useEffect(()=>{let b=!0;return F.getBreakdown(t,e.path).then(E=>{b&&(c(E.items),h(E.items.map(()=>!0)))}).catch(()=>{b&&(c([]),h([]))}),()=>{b=!1}},[t,e.path]);const S={project:t,title:e.title,prdPath:e.path,branchFrom:Ase(e.path)},y=l.filter((b,E)=>d[E]),v=async()=>{if(y.length){p(!0);try{await i(t,e.path,y)}finally{p(!1)}}};return r.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},children:[r.jsxs("div",{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:12,marginBottom:14},children:[r.jsxs("div",{style:{minWidth:0},children:[r.jsx("div",{className:"hn-eyebrow",style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",marginBottom:4},children:e.path}),r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[r.jsx("div",{style:{fontFamily:"var(--font-sans)",fontSize:18,fontWeight:700,color:"var(--text-strong)"},children:e.title}),r.jsx(CA,{prd:e})]})]}),r.jsxs("div",{style:{display:"flex",gap:8,flexShrink:0,alignItems:"center"},children:[r.jsx(Do,{href:b=>F.prdDownloadUrl(t,e.path,b),disabled:s===null}),r.jsx(B,{size:"sm",variant:"ghost",leftIcon:"list-checks",onClick:()=>_(!0),children:"Take ke backlog"}),r.jsx(B,{size:"sm",leftIcon:"split",onClick:()=>n(t,e.path),children:"Breakdown ke backlog"})]})]}),l.length>0&&r.jsxs("div",{style:{border:"1px solid var(--brass-200)",borderRadius:"var(--radius-sm)",background:"var(--brass-50)",padding:12,marginBottom:14},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:8,gap:8},children:[r.jsxs("div",{style:{fontFamily:"var(--font-sans)",fontWeight:700,fontSize:13,color:"var(--brass-700)"},children:["Usulan backlog paralel (",y.length,"/",l.length,")"]}),r.jsx(B,{size:"sm",leftIcon:"plus",disabled:!y.length||m,onClick:v,children:m?"Membuat…":`Buat ${y.length} backlog`})]}),l.map((b,E)=>r.jsxs("label",{style:{display:"flex",gap:8,alignItems:"flex-start",padding:"6px 0",borderTop:E?"1px solid var(--border-hair)":"none",cursor:"pointer"},children:[r.jsx("input",{type:"checkbox",checked:d[E]??!1,onChange:k=>h(T=>T.map((A,M)=>M===E?k.target.checked:A))}),r.jsxs("div",{style:{minWidth:0},children:[r.jsxs("div",{style:{fontSize:13,fontWeight:600,color:"var(--text-strong)",display:"flex",alignItems:"center",gap:6,flexWrap:"wrap"},children:[b.title," ",r.jsx(Ne,{tone:"brass",size:"sm",children:b.priority})]}),b.outcome&&r.jsx("div",{style:{fontSize:12,color:"var(--text-subtle)"},children:b.outcome})]})]},E))]}),r.jsx("div",{style:{flex:"1 1 auto",minHeight:0,overflowY:"auto"},children:s===null?r.jsx(ue,{kind:"loading",title:"Memuat PRD…"}):r.jsx(Ar,{text:s,name:e.name})}),g&&r.jsx(Tt,{open:!0,onClose:()=>_(!1),icon:"list-checks",eyebrow:"PRD → backlog",title:"Take PRD ke backlog",footer:r.jsx(B,{variant:"ghost",size:"sm",onClick:()=>_(!1),children:"Batal"}),children:r.jsxs("div",{style:{display:"grid",gap:16},children:[r.jsxs("div",{children:[r.jsx(B,{leftIcon:"lightbulb",onClick:()=>{_(!1),a({...S,kind:"brief",context:`Dari PRD: ${e.path}`,outcome:""})},children:"Sebagai feature brief"}),r.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginTop:6,lineHeight:1.5},children:"Sesi menjalankan pipeline penuh: brainstorm → objective → spec → plan → execute."})]}),r.jsxs("div",{children:[r.jsx(B,{leftIcon:"target",variant:"secondary",onClick:()=>{_(!1),a({...S,kind:"goal",context:"",outcome:"",goal:`Wujudkan PRD ${e.path}`})},children:"Sebagai goal"}),r.jsx("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginTop:6,lineHeight:1.5},children:"Sesi dua fase (Goal → Verifikasi) yang langsung mengejar goal-nya, tanpa brainstorm, spec, maupun plan. Mode goal selalu aktif."})]})]})})]})}function koe(e){const t=[],a=new Map;for(const n of e){let i=a.get(n.projectId);i||(i={projectId:n.projectId,projectName:n.projectName,items:[]},a.set(n.projectId,i),t.push(n.projectId)),i.items.push(n)}return t.map(n=>a.get(n))}function xoe({prd:e,active:t,onSelect:a}){const[n,i]=f.useState(!1);return r.jsxs("button",{onClick:a,onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),style:{display:"block",width:"100%",textAlign:"left",cursor:"pointer",border:"none",borderRadius:"var(--radius-sm)",padding:"8px 10px",marginBottom:2,background:t?"var(--brass-100)":n?"var(--bone-200)":"transparent"},children:[r.jsxs("div",{style:{display:"flex",alignItems:"center",gap:7,marginBottom:3,flexWrap:"wrap"},children:[r.jsx(Ie,{name:"scroll-text",size:13,color:t?"var(--brass-700)":"var(--brass-500)"}),r.jsx("span",{style:{fontFamily:"var(--font-sans)",fontSize:14,fontWeight:600,color:t?"var(--brass-700)":"var(--text-strong)"},children:e.title}),r.jsx(CA,{prd:e}),e.live&&r.jsx(Ne,{tone:"brass",size:"sm",children:"sesi hidup"})]}),r.jsx("div",{style:{fontFamily:"var(--font-mono)",fontSize:10,color:"var(--text-subtle)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:e.path})]})}function Toe({projects:e,projectFilter:t,onProjectFilter:a,onNewPrd:n,onTakeToBacklog:i,onStartBreakdown:s,onMaterialize:o,dataVersion:l}){const[c,d]=f.useState([]),[h,m]=rt("prd","sel",null,Io),[p,g]=f.useState("list"),_=f.useMemo(()=>c.find(R=>R.slug===h)??null,[c,h]),S=f.useCallback(R=>m(R?R.slug:null),[m]),[y,v]=f.useState(!1),[b,E]=rt("prd","status","all",ri("all",...Df)),k=t==="all",T=k?"":t;f.useEffect(()=>{S(null)},[t,b]),f.useEffect(()=>{let R=!0;return(k?F.listAllPrds():T?F.listPrds(T):Promise.resolve({items:[]})).then(j=>{R&&d(j.items)}).catch(()=>{R&&d([])}),()=>{R=!1}},[t,l]);const A=b==="all"?c:c.filter(R=>R.status===b),M=koe(A),x=_?_.projectId||T:"",P=[{value:"all",label:"Semua project"}].concat(e.map(R=>({value:R.id,label:R.name})));return r.jsxs("div",{style:J0,children:[r.jsxs("div",{className:"hn-stack-mobile",style:{...Mr,display:"flex",alignItems:"center",justifyContent:"space-between",gap:12,marginBottom:18},children:[r.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",alignItems:"center",gap:8},children:[r.jsx(xe,{size:"sm",value:t,"aria-label":"Project",onChange:R=>a(R.target.value),options:P}),r.jsx(xe,{size:"sm",value:b,"aria-label":"Status PRD",onChange:R=>E(R.target.value),options:[{value:"all",label:"Semua status"}].concat(Df.map(R=>({value:R,label:R})))}),r.jsx(Mh,{screen:"prd",active:b==="all"?0:1})]}),r.jsx(B,{size:"sm",leftIcon:"plus",onClick:()=>v(!0),children:"PRD baru"})]}),r.jsx(No,{ariaLabel:"Panel PRD",active:p,onActiveChange:R=>g(R),masterWidth:264,panels:[{id:"list",label:"Daftar",className:"hn-panel-flex",content:r.jsx("aside",{"aria-label":"Daftar PRD",style:{width:"100%",minHeight:0,overflowY:"auto",borderRight:"1px solid var(--border-hair)",paddingRight:12},children:c.length===0?r.jsx(ue,{kind:"empty",icon:"scroll-text",title:"Belum ada PRD",hint:"Buat PRD dari brief + brainstorm; hanoman menulisnya ke docs/prd/ lalu bisa di-take jadi backlog.",action:()=>v(!0),actionLabel:"PRD baru"}):A.length===0?r.jsx(ue,{kind:"empty",icon:"filter",compact:!0,title:`Tak ada PRD berstatus "${b}"`,hint:"Longgarkan filter status untuk melihat PRD lainnya.",action:()=>E("all"),actionLabel:"Semua status"}):M.map(R=>r.jsxs("div",{style:{marginBottom:10},children:[k&&r.jsx("div",{className:"hn-eyebrow",style:{fontFamily:"var(--font-sans)",fontSize:11,fontWeight:600,letterSpacing:.3,textTransform:"uppercase",color:"var(--text-subtle)",padding:"6px 10px 4px"},children:R.projectName}),R.items.map(G=>r.jsx(xoe,{prd:G,active:(_==null?void 0:_.path)===G.path&&(_==null?void 0:_.projectId)===G.projectId,onSelect:()=>{S(G),g("detail")}},`${G.projectId}:${G.path}`))]},R.projectId))})},{id:"detail",label:"Detail",className:"hn-panel-flex",content:r.jsx("div",{style:{flex:"1 1 auto",minHeight:0},children:_?r.jsx(Eoe,{prd:_,projectId:x,onTake:R=>i(R),onStartBreakdown:s,onMaterialize:o}):r.jsx(ue,{kind:"empty",icon:"scroll-text",title:"Pilih PRD",hint:"Klik dokumen di daftar kiri untuk melihat isinya, lalu take ke backlog."})})}]}),y&&r.jsx(TA,{projects:e,defaultProject:T,onClose:()=>v(!1),onCreate:(R,G)=>{v(!1),n(R,G)}})]})}/**
7486
7486
  * Copyright (c) 2014-2024 The xterm.js authors. All rights reserved.
package/web/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
7
  <title>hanoman</title>
8
- <script type="module" crossorigin src="/assets/index-K11GZzfg.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-C7l4ixak.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-DeGA9N3Z.css">
10
10
  </head>
11
11
  <body>